Validate NetBIOS Domain Name to see if its in use or just test to see if its valid. Powershell/C#


 

Recently someone in the forums asked how they could check to see if a NetBIOS Domain Name was in use or not. Come to find out there isn’t a .NET methods for doing this that I could find but there is an API function for that. First I’ll show the C# and then I’ll show how to use it in Powershell. Creating a C# console app was how I went about figuring this out for Powershell.

First I took a look at the API which looked pretty easy to bring in to C# and then I called it within my Main() function. Here is the complete C# console code.

using System;

using System.Runtime.InteropServices;

 

public class NetworkUtil

{

    [DllImport("Netapi32.dll",SetLastError=true,CharSet=CharSet.Unicode)]

    public static extern UInt32 NetValidateName(string lpServer,string lpName, string lpAccount,string lpPassword, int NameType);

 

    static void Main()

    {

        UInt32 rtn = NetValidateName(null, "jrich-pc", null, null, 1);

        Console.WriteLine(rtn);

        Console.ReadKey();

    }

}

So lets walk through this. First I only included (using) the System and InteropServices (PInvoke) and then created a class for this. I used NetworkUtil so that I could extend my class in my NetStat powershell cmdlet if I wanted (I suspect this will grow over time).

I then used the DLLImport to pull in the function from the .dll file. I’ve included the SetLastError simply because I saw it on most but its not really needed. The CharSet being set to Unicode is very important. That part threw me for a loop. The docs don’t really talk about it and the only reference is in their example. I stumbled across it when looking at another example of a similar call (www.pinvoke.net)

The question that should be running through your mind right about now is, how did you convert the C++ function signature to C#? The answer is simple, I guessed based on what it implied. The first time I started to play with PInvoke stuff I was surprised at how forgiving the types were. Granted this can get you in trouble, but if you know what you are expecting in return, you can go from there and tweak it.

The C++ signature is as follows.

NET_API_STATUS NetValidateName( __in LPCWSTR lpServer, __in LPCWSTR lpName, __in LPCWSTR lpAccount, __in LPCWSTR lpPassword, __in NETSETUP_NAME_TYPE NameType );

 

The return type is a structure of error codes that boil down to numbers, so I said hey, lets make it a INT32, I later found a negative error code so I changed it to UINT32, you almost never see negative numbers (I’ll look at that in a bit). Then we need to keep the name the same. For the param’s we’ll see most are LPCWSTR which is a string (docs tell you and the STR gives it away) so I simple made them all strings in the C# code. The last param is of type NETSETUP_NAME_TYPE which is defined in the docs to be a simple ENUM that is 0-5. At first I created the ENUM but then decided it was easy enough to just send it a number and if I needed to change it I’d reference the docs.

Then I get to testing this from my main function with a simple call.

UInt32 rtn = NetValidateName(null, "jrich-pc", null, null, 1);

Reading the docs you’ll see the inputs are pretty basic;

Server – The server to query again, null is the local machine, this should be fine for most.

Name – The name you want to query for

Username and Password – If you query a server (an AD server) you can provide creds, if you don’t it uses the current context (you)

Name Type – This is the type of query you want to preform.

The Name Type can be found on the docs page, but I’ve copied them here for simple reference. The two that seem to be of most value are 1 and 3.

Value

Meaning

NetSetupUnknown

0

The nametype is unknown. If this value is used, the NetValidateName function fails with ERROR_INVALID_PARAMETER.

NetSetupMachine

1

Verify that the NetBIOS computer name is valid and that it is not in use.

NetSetupWorkgroup

2

Verify that the workgroup name is valid.

NetSetupDomain

3

Verify that the domain name exists and that it is a domain.

NetSetupNonExistentDomain

4

Verify that the domain name is not in use.

NetSetupDnsMachine

5

Verify that the DNS computer name is valid.

This value is supported on Windows 2000 and later. The application must be compiled with _WIN32_WINNT >= 0x0500 to use this value.

 

These are pretty well documented and make good sense. As I said typically you’ll use 1 and 3 and maybe even 4 depending on how you want to code your app.

 

The part that was hardest was tracking down these error codes. I found the best way was to google the display names that the docs showed. Here is a table I made with the Error Codes I was able to track down.

NET_API_STATUS Error Codes

Number

Name

Meaning

50

ERROR_NOT_SUPPORTED

 

52

ERROR_DUP_NAME

It found what you were looking for

53

ERROR_BAD_NETPATH

It wasn’t able to connect to your query server

1210

ERROR_INVALID_COMPUTERNAME

 

1355

ERROR_NO_SUCH_DOMAIN

 

2351

NERR_InvalidComputer

 

2695

NERR_InvalidWorkgroupName

 

9556

DNS_ERROR_NON_RFC_NAME

 

9560

DNS_ERROR_INVALID_NAME_CHAR

 

2147549463

RPC_E_REMOTE_DISABLED

Found query server but RPC wasn’t available

 

Most of these codes are pretty obvious and should make sense once you start to test it.

 

Powershell!

Now, lets use this in powershell. Its actually pretty easy once we figure that part out.

Add-Type -TypeDefinition @"
using System;
using System.Runtime.InteropServices;

public class NetworkUtil
{
    [DllImport("Netapi32.dll",CharSet=CharSet.Unicode)]
    public static extern UInt32 NetValidateName(string lpServer,string lpName,string lpAccount,string lpPassword,
        int NameType);
}
"@

Function Test-NetBIOSName{

param([string] $Name, [int] $NameType)
[NetworkUtil]::NetValidateName($null,$name,$null,$null,$NameType)
}

#TEST

Test-NetBIOSName “myserver” 1

The function I created is very basic. You could tweak the param’s to validate input and the such, but I’ll leave that up to you.

Hope this helps!

Advertisements

About jrich

I am the Solutions Architect for Apex Learning in Seattle WA. I've been working with computers since I was 13. Started programming when I was 14. Had my first IT job as tech support at an ISP at the age of 15 and became a network admin at the age of 17. Since then I've worked at a variety of small to mid size companies supporting, maintaining and developing all aspects of IT. Mostly working with Windows based networks but have recently been working with Solaris system as well. I created this blog mostly as a place for me to take my own notes, but also share things that I had a hard time finding the info for.

Posted on July 11, 2011, in .NET, C#, WMF (Powershell/WinRM) and tagged , . Bookmark the permalink. Leave a comment.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: