netserverenum (netapi32)
Last changed: -64.22.251.193

.
Summary
Enumerate all the servers on a domain or workgroup, returning an arraylist of SERVER_INFO_101 structs

C# Signature:

[DllImport("netapi32.dll",EntryPoint="NetServerEnum")]
public static extern int NetServerEnum(
    [MarshalAs(UnmanagedType.LPWStr)] string servername,
    int level,
    out IntPtr bufptr,
    int prefmaxlen,
    out int entriesread,
    out int totalentries,
    int servertype,
    [MarshalAs(UnmanagedType.LPWStr)] string domain,
    IntPtr resume_handle);

[DllImport("netapi32.dll",EntryPoint="NetApiBufferFree")]
public static extern int NetApiBufferFree(IntPtr buffer);

VB Signature:

Private Declare Unicode Function NetServerEnum Lib "netapi32" _
    (ByVal Servername As IntPtr, _
    ByVal Level As Integer, _
    ByRef bufptr As IntPtr, _
    ByVal PrefMaxLen As Integer, _
    ByRef entriesread As Integer, _
    ByRef TotalEntries As Integer, _
    ByVal serverType As Integer, _
    ByVal Domain As IntPtr, _
    ByVal ResumeHandle As IntPtr) As Integer

Notes:

None.

Tips & Tricks:

Please add some!

Sample Code:

Sample Class #1

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Security;

namespace Microsoft.Win32
{
    internal static partial class NativeMethods
    {
        const int MAX_PREFERRED_LENGTH = -1;

        [Flags]
        public enum ServerTypes : uint
        {
            Workstation = 0x00000001,
            Server = 0x00000002,
            SqlServer = 0x00000004,
            DomainCtrl= 0x00000008,
            BackupDomainCtrl= 0x00000010,
            TimeSource= 0x00000020,
            AppleFilingProtocol = 0x00000040,
            Novell= 0x00000080,
            DomainMember = 0x00000100,
            PrintQueueServer = 0x00000200,
            DialinServer = 0x00000400,
            XenixServer = 0x00000800,
            UnixServer = 0x00000800,
            NT = 0x00001000,
            WindowsForWorkgroups = 0x00002000,
            MicrosoftFileAndPrintServer= 0x00004000,
            NTServer = 0x00008000,
            BrowserService = 0x00010000,
            BackupBrowserService= 0x00020000,
            MasterBrowserService= 0x00040000,
            DomainMaster = 0x00080000,
            OSF1Server = 0x00100000,
            VMSServer = 0x00200000,
            Windows = 0x00400000,
            DFS = 0x00800000,
            NTCluster = 0x01000000,
            TerminalServer= 0x02000000,
            VirtualNTCluster = 0x04000000,
            DCE = 0x10000000,
            AlternateTransport = 0x20000000,
            LocalListOnly = 0x40000000,
            PrimaryDomain = 0x80000000,
            All = 0xFFFFFFFF
        };

        public enum ServerPlatform
        {
            DOS = 300,
            OS2 = 400,
            NT = 500,
            OSF = 600,
            VMS = 700
        }

        [DllImport("Netapi32", CharSet = CharSet.Auto, SetLastError = true), SuppressUnmanagedCodeSecurityAttribute]
        private static extern int NetServerEnum(
            [MarshalAs(UnmanagedType.LPWStr)] string servernane, // must be null
            int level,
            out IntPtr bufptr,
            int prefmaxlen,
            out int entriesread,
            out int totalentries,
            ServerTypes servertype,
            [MarshalAs(UnmanagedType.LPWStr)] string domain, // null for login domain
            IntPtr resume_handle // Must be IntPtr.Zero
            );

        [DllImport("Netapi32", SetLastError = true), SuppressUnmanagedCodeSecurityAttribute]
        private static extern int NetApiBufferFree(IntPtr pBuf);

        [StructLayout(LayoutKind.Sequential)]
        private struct SERVER_INFO_100
        {
            public ServerPlatform sv100_platform_id;
            [MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
            public string sv100_name;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct NetworkComputerInfo // SERVER_INFO_101
        {
            ServerPlatform sv101_platform_id;
            [MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
            string sv101_name;
            int sv101_version_major;
            int sv101_version_minor;
            ServerTypes sv101_type;
            [MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
            string sv101_comment;

            public ServerPlatform Platform { get { return sv101_platform_id; } }
            public string Name { get { return sv101_name; } }
            public string Comment { get { return sv101_comment; } }
            public ServerTypes ServerTypes { get { return sv101_type; } }
            public Version Version { get { return new Version(sv101_version_major, sv101_version_minor); } }
        };

        public static IEnumerable<string> GetNetworkComputerNames(ServerTypes serverTypes = ServerTypes.Workstation | ServerTypes.Server, string domain = null)
        {            
            IntPtr bufptr = IntPtr.Zero;
            try
            {
                int entriesRead, totalEntries;
                IntPtr resumeHandle = IntPtr.Zero;

                int ret = NetServerEnum(null, 100, out bufptr, MAX_PREFERRED_LENGTH, out entriesRead, out totalEntries, serverTypes, domain, resumeHandle);
                if (ret == 0)
                    return Array.ConvertAll<SERVER_INFO_100, string>(InteropUtil.ToArray<SERVER_INFO_100>(bufptr, entriesRead), si => si.sv100_name);
                throw new System.ComponentModel.Win32Exception(ret);
            }
            finally
            {
                NetApiBufferFree(bufptr);
            }
        }

        public static IEnumerable<NetworkComputerInfo> GetNetworkComputerInfo(ServerTypes serverTypes = ServerTypes.Workstation | ServerTypes.Server, string domain = null)
        {
            IntPtr bufptr = IntPtr.Zero;
            try
            {
                int entriesRead, totalEntries;
                IntPtr resumeHandle = IntPtr.Zero;

                int ret = NetServerEnum(null, 101, out bufptr, MAX_PREFERRED_LENGTH, out entriesRead, out totalEntries, serverTypes, domain, resumeHandle);
                if (ret == 0)
                    return InteropUtil.ToArray<NetworkComputerInfo>(bufptr, entriesRead);
                throw new System.ComponentModel.Win32Exception(ret);
            }
            finally
            {
                NetApiBufferFree(bufptr);
            }
        }
    }
}

namespace System.Runtime.InteropServices
{
    internal static class InteropUtil
    {
        public static T ToStructure<T>(IntPtr ptr)
        {
            return (T)Marshal.PtrToStructure(ptr, typeof(T));
        }

        /// <summary>
        /// Converts an <see cref="IntPtr"/> that points to a C-style array into a CLI array.
        /// </summary>
        /// <typeparam name="T">Type of native structure used by the C-style array.</typeparam>
        /// <param name="ptr">The <see cref="IntPtr"/> pointing to the native array.</param>
        /// <param name="count">The number of items in the native array.</param>
        /// <returns>An array of type <typeparamref name="T"/> containing the elements of the native array.</returns>
        public static T[] ToArray<T>(IntPtr ptr, int count)
        {
            IntPtr tempPtr;
            T[] ret = new T[count];
            int stSize = Marshal.SizeOf(typeof(T));
            for (int i = 0; i < count; i++)
            {
                tempPtr = new IntPtr(ptr.ToInt64() + (i * stSize));
                ret[i] = ToStructure<T>(tempPtr);
            }
            return ret;
        }
    }
}

Sample Class #2

using System;
using System.Runtime.InteropServices;
using System.Collections ;

namespace Win32
{
    /// <summary>
    /// Summary description for Class1.
    /// </summary>
    ///
    public class NetApi32
    {
        // constants
        public const uint ERROR_SUCCESS        = 0;
        public const uint ERROR_MORE_DATA    = 234;
        public enum SV_101_TYPES:uint
        {
            SV_TYPE_WORKSTATION= 0x00000001,
            SV_TYPE_SERVER= 0x00000002,
            SV_TYPE_SQLSERVER = 0x00000004,
            SV_TYPE_DOMAIN_CTRL= 0x00000008,
            SV_TYPE_DOMAIN_BAKCTRL= 0x00000010,
            SV_TYPE_TIME_SOURCE= 0x00000020,
            SV_TYPE_AFP= 0x00000040,
            SV_TYPE_NOVELL= 0x00000080,
            SV_TYPE_DOMAIN_MEMBER = 0x00000100,
            SV_TYPE_PRINTQ_SERVER = 0x00000200,
            SV_TYPE_DIALIN_SERVER = 0x00000400,
            SV_TYPE_XENIX_SERVER = 0x00000800,
            SV_TYPE_SERVER_UNIX = 0x00000800,
            SV_TYPE_NT = 0x00001000,
            SV_TYPE_WFW = 0x00002000,
            SV_TYPE_SERVER_MFPN= 0x00004000,
            SV_TYPE_SERVER_NT = 0x00008000,
            SV_TYPE_POTENTIAL_BROWSER = 0x00010000,
            SV_TYPE_BACKUP_BROWSER= 0x00020000,
            SV_TYPE_MASTER_BROWSER= 0x00040000,
            SV_TYPE_DOMAIN_MASTER = 0x00080000,
            SV_TYPE_SERVER_OSF= 0x00100000,
            SV_TYPE_SERVER_VMS= 0x00200000,
            SV_TYPE_WINDOWS= 0x00400000,
            SV_TYPE_DFS= 0x00800000,
            SV_TYPE_CLUSTER_NT= 0x01000000,
            SV_TYPE_TERMINALSERVER= 0x02000000,
            SV_TYPE_CLUSTER_VS_NT = 0x04000000,
            SV_TYPE_DCE= 0x10000000,
            SV_TYPE_ALTERNATE_XPORT= 0x20000000,
            SV_TYPE_LOCAL_LIST_ONLY= 0x40000000,
            SV_TYPE_DOMAIN_ENUM= 0x80000000,
            SV_TYPE_ALL= 0xFFFFFFFF
        };

        [StructLayout(LayoutKind.Sequential)]
            public struct SERVER_INFO_101
        {
            [MarshalAs(System.Runtime.InteropServices.UnmanagedType.U4)]
            public UInt32 sv101_platform_id;
            [MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
            public string sv101_name;

            [MarshalAs(System.Runtime.InteropServices.UnmanagedType.U4)] public UInt32 sv101_version_major;
            [MarshalAs(System.Runtime.InteropServices.UnmanagedType.U4)] public UInt32 sv101_version_minor;
            [MarshalAs(System.Runtime.InteropServices.UnmanagedType.U4)] public UInt32 sv101_type;
            [MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)] public string sv101_comment;
        };

        public enum PLATFORM_ID
        {
            PLATFORM_ID_DOS = 300,
            PLATFORM_ID_OS2 = 400,
            PLATFORM_ID_NT = 500,
            PLATFORM_ID_OSF = 600,
            PLATFORM_ID_VMS = 700
        }

        [DllImport("netapi32.dll",EntryPoint="NetServerEnum")]
        public static extern int NetServerEnum( [MarshalAs(UnmanagedType.LPWStr)]string servername,
            int level,
            out IntPtr bufptr,
            int prefmaxlen,
            ref int entriesread,
            ref int totalentries,
            SV_101_TYPES servertype,
            [MarshalAs(UnmanagedType.LPWStr)]string domain,
            IntPtr resume_handle);

        [DllImport("netapi32.dll",EntryPoint="NetApiBufferFree")]
        public static extern int
            NetApiBufferFree(IntPtr buffer);

        [DllImport ("Netapi32", CharSet=CharSet.Unicode)]
        private static extern int NetMessageBufferSend(
            string servername,
            string msgname,
            string fromname,
            string buf,
            int buflen);

        public static int NetMessageSend(string serverName,string messageName,string fromName,string strMsgBuffer, int iMsgBufferLen)
        {
            return NetMessageBufferSend(serverName,messageName,fromName,strMsgBuffer,iMsgBufferLen*2);
        }

        public static ArrayList GetServerList( NetApi32.SV_101_TYPES ServerType)
        {
            int entriesread=0,totalentries=0;
            ArrayList alServers = new  ArrayList();

            do
            {
                // Buffer to store the available servers
                // Filled by the NetServerEnum function
                IntPtr buf = new IntPtr();

                SERVER_INFO_101 server;
                int ret = NetServerEnum(null,101,out buf,-1,
                    ref entriesread,ref totalentries,
                    ServerType,null,IntPtr.Zero);

                // if the function returned any data, fill the tree view
                if(    ret == ERROR_SUCCESS    ||
                    ret == ERROR_MORE_DATA    ||
                    entriesread > 0)
                {
                    IntPtr ptr = buf;

                    for(int i=0; i<entriesread; i++)
                    {
                        // cast pointer to a SERVER_INFO_101 structure
                        server = (SERVER_INFO_101)Marshal.PtrToStructure(ptr,typeof(SERVER_INFO_101));

                        //Cast the pointer to a ulong so this addition will work on 32-bit or 64-bit systems.
                        ptr = (IntPtr)((ulong)ptr + (ulong)Marshal.SizeOf(server));

                        // add the machine name and comment to the arrayList.
                        //You could return the entire structure here if desired
                         alServers.Add( server);
                    }
                }

                // free the buffer
                NetApiBufferFree(buf);                
            }
            while
                (
                entriesread < totalentries &&
                entriesread != 0
                );

             return alServers;
        }
    }
}

Alternative Managed API:

Do you know one? Please contribute it!

The System.Data.Sql.SqlDataSourceEnumerator class is an alternative to this API, for enumerating SQL Servers on a network.

Documentation