94

How can you get the FQDN of a local machine in C#?

Sam
  • 40,644
  • 36
  • 176
  • 219

13 Answers13

148

NOTE: This solution only works when targeting the .NET 2.0 (and newer) frameworks.

using System;
using System.Net;
using System.Net.NetworkInformation;
//...

public static string GetFQDN()
{
    string domainName = IPGlobalProperties.GetIPGlobalProperties().DomainName;
    string hostName = Dns.GetHostName();

    domainName = "." + domainName;
    if(!hostName.EndsWith(domainName))  // if hostname does not already include domain name
    {
        hostName += domainName;   // add the domain name part
    }

    return hostName;                    // return the fully qualified name
}

UPDATE

Since a lot of people have commented that Sam's Answer is more concise I've decided to add some comments to the answer.

The most important thing to note is that the code I gave is not equivalent to the following code:

Dns.GetHostEntry("LocalHost").HostName

While in the general case when the machine is networked and part of a domain, both methods will generally produce the same result, in other scenarios the results will differ.

A scenario where the output will be different is when the machine is not part of a domain. In this case, the Dns.GetHostEntry("LocalHost").HostName will return localhost while the GetFQDN() method above will return the NETBIOS name of the host.

This distinction is important when the purpose of finding the machine FQDN is to log information, or generate a report. Most of the time I've used this method in logs or reports that are subsequently used to map information back to a specific machine. If the machines are not networked, the localhost identifier is useless, whereas the name gives the needed information.

So ultimately it's up to each user which method is better suited for their application, depending on what result they need. But to say that this answer is wrong for not being concise enough is superficial at best.

See an example where the output will be different: http://ideone.com/q4S4I0

Community
  • 1
  • 1
Mike Dinescu
  • 54,171
  • 16
  • 118
  • 151
  • 2
    Using `Dns.GetHostEntry("LocalHost").HostName` I get always the hostname (not netbios) with the primary domain suffix. This doesn't depend on whether the machine is part of a domain, a DNS server is reachable or the netzwork is connected. Probably I don't understand your explanation but the result is what I expect. (Machine: W2008R2; .net 4.0; netbiosname:TESTNAME-VERYLO hostname: TESTNAME-VERYLONG) – marsh-wiggle Nov 20 '14 at 08:43
  • Why do you use `Dns.GetHostName()` for `hostName` instead of using the `HostName` property of the `IPGlobalProperties` object you already have, one line above? – Xharlie Dec 12 '14 at 15:04
  • @Xharlie because the `IPGlobalProperties` hostname property returns the NetBIOS name, whereas `Dns.GetHostName()` returns the DNS host name. – Mike Dinescu Dec 12 '14 at 16:09
  • 2
    the `EndsWith` check is broken for hostnames that end with the same letters as the domain name (e.g. a host MYHOST in domain OST), should probably be `EndsWith("." + domainName)` – user3391859 Nov 05 '15 at 17:29
  • Generally the domain is of the form "DOMAIN.TLD" but yeah, your check method would be better - updated to reflect – Mike Dinescu Nov 05 '15 at 19:36
  • Sometimes, Dns.GetHostEntry gives socket error. With a valid ipaddress. – Pradip Jul 06 '16 at 06:40
  • 9
    If domainName is empty then this returns `hostName.`. There should be a `!String.isNullorEmpty(domainName)` check – alaney Jul 15 '16 at 17:35
  • @RodgerTheGreat The ideone example does it. I edited the answer to mirror that. Actually it uses the EndsWith a little better. Btw. I have tried this example with 'Dns.GetHostEntry("LocalHost").HostName' on an virtual machine with no domain and it worked. – JackGrinningCat Jun 21 '18 at 12:33
  • It is not guaranteed that this returns a valid name in DNS, since this may just pull the "domain name" for the computer based on a registry setting. If this is going to be used for network communcation, I think one should use something along the lines of the win32 API DnsQuery_A with DNS_QUERY_WIRE_ONLY flag to validate that the name actually works. – Elliott Beach Dec 13 '22 at 15:43
  • A “fully qualified domain name” is not the same thing as a valid domain name in DNS. I think the answer I posted even goes to say that. If there are network configuration errors and what you want to do is detect those then yes, have the FQDN as configured on the machine is not enough. – Mike Dinescu Dec 18 '22 at 15:40
  • @MikeDinescu No, your answer does not describe the distinction between “fully qualified domain name” and a valid domain name in DNS; you mention the case where the machine is not networked or does not have a domain, but this is not the only case. In the case I'm concerned with, by the way, I observe, somewhat disappointly, the same behavior from Dns.GetHostEntry. – Elliott Beach Dec 21 '22 at 17:18
64

A slight simplification of Miky D's code

    public static string GetLocalhostFqdn()
    {
        var ipProperties = IPGlobalProperties.GetIPGlobalProperties();
        return string.Format("{0}.{1}", ipProperties.HostName, ipProperties.DomainName);
    }
Matt Z
  • 1,294
  • 1
  • 9
  • 12
  • 5
    Unlike Micky D's code this returns the hostname with an appended fullstop if the machine is not a member of a domain. – Bosco Feb 12 '13 at 09:08
  • 1
    Also, this uses the NetBIOS name instead of the DNS host name. I believe NetBIOS names are only suitable within LANs. – Sam Jun 13 '13 at 04:56
  • Perhaps add a `.Trim(".")` to the the last line to get rid of the . if it exists. – David d C e Freitas Nov 26 '13 at 00:51
32

This is covered by this article. This technique is more brief than the accepted answer and probably more reliable than the next most-voted answer. Note that as far as I understand, this doesn't use NetBIOS names, so it should be suitable for Internet use.

.NET 2.0+

Dns.GetHostEntry("LocalHost").HostName

.NET 1.0 - 1.1

Dns.GetHostByName("LocalHost").HostName
Community
  • 1
  • 1
Sam
  • 40,644
  • 36
  • 176
  • 219
  • @DexterLegaspi - Sam's answer is a good one (I've even up-voded it myself) but it's not equivalent to my answer, nor necessarily better. Please see my updated answer for details. – Mike Dinescu Nov 19 '14 at 19:09
  • 1
    @MikeDinescu the question is how to get FQDN, which connotes that the machine is on a network and part of a domain. the accepted answer does the job but Sam's answer is more "precise" (for the lack of a better term) – Dexter Legaspi Nov 20 '14 at 14:55
  • 5
    this is the correct answer! but instead of doing `Dns.GetHostEntry("LocalHost").HostName` you better pass an empty string like so: `Dns.GetHostEntry("").HostName` – paulgutten Mar 08 '19 at 14:07
  • @paulgutten What makes you say that this is the correct answer? I don't see it. – Elliott Beach Dec 18 '22 at 00:55
17

Here it is in PowerShell, for the heck of it:

$ipProperties = [System.Net.NetworkInformation.IPGlobalProperties]::GetIPGlobalProperties()
"{0}.{1}" -f $ipProperties.HostName, $ipProperties.DomainName
halr9000
  • 9,879
  • 5
  • 33
  • 34
15

And for Framework 1.1 is as simple as this:

System.Net.Dns.GetHostByName("localhost").HostName

And then remove the machine NETBIOS name to retrieve only the domainName

Paul Kohler
  • 2,684
  • 18
  • 31
javizcaino
  • 151
  • 1
  • 2
  • 1
    Here in 2013, `GetHostByName("localhost")` is obsoleted. VS 2010 suggested I use `GetHostEntry("localhost")` instead, which works fine. – piedar Jul 08 '13 at 16:33
  • @piedar, you might have missed the bit about this being for .NET 1.1. – Sam Feb 27 '14 at 22:17
  • I wanted to add updated information to this answer, as it was the simplest and thus my favorite. I probably didn't scroll far enough to see your answer, which had indeed rendered my comment unnecessary. – piedar Feb 28 '14 at 17:08
11

You can try the following:

return System.Net.Dns.GetHostEntry(Environment.MachineName).HostName;

This shoud give you the FQDN of the current local machine (or you can specify any host).

Kiquenet
  • 14,494
  • 35
  • 148
  • 243
UT-Fan-05
  • 406
  • 4
  • 8
5

A slight improvement on Matt Z's answer so that a trailing full stop isn't returned if the computer is not a member of a domain:

public static string GetLocalhostFqdn()
{
    var ipProperties = IPGlobalProperties.GetIPGlobalProperties();
    return string.IsNullOrWhiteSpace(ipProperties.DomainName) ? ipProperties.HostName : string.Format("{0}.{1}", ipProperties.HostName, ipProperties.DomainName);
}
Bosco
  • 935
  • 10
  • 18
  • Note that I think this uses the NetBIOS host name, so it may not be suitable for Internet use. – Sam Jun 13 '13 at 05:16
2

Used this as one of my options to combine host name and domain name for building a report, added the generic text to fill in when domain name was not captured, this was one of the customers requirements.

I tested this using C# 5.0, .Net 4.5.1

private static string GetHostnameAndDomainName()
{
       // if No domain name return a generic string           
       string currentDomainName = IPGlobalProperties.GetIPGlobalProperties().DomainName ?? "nodomainname";
       string hostName = Dns.GetHostName();

    // check if current hostname does not contain domain name
    if (!hostName.Contains(currentDomainName))
    {
        hostName = hostName + "." + currentDomainName;
    }
    return hostName.ToLower();  // Return combined hostname and domain in lowercase
} 

Built using ideas from Miky Dinescu solution.

1

We have implemented suggested result to use this way:

return System.Net.Dns.GetHostEntry(Environment.MachineName).HostName;

However, turned out that this does not work right when computer name is longer than 15 characters and using NetBios name. The Environment.MachineName returns only partial name and resolving host name returns same computer name.

After some research we found a solution to fix this problem:

System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName()).HostName

This resolved all problems including computer name.

btomas
  • 391
  • 4
  • 12
  • This will throw an exception, and most other solutions suggested will fail as well, if you have a computer which has been given a name by the user containing characters not from a-z, 0-9,'.', '-'. So expect problems if you have users in Asia or similar. GetHostName will have those characters replaced by '?'. That's why I prefer GetHostByName("localhost").HostName which shows the actual computer name. – Göran Sep 10 '20 at 08:58
1

None of the answers provided that I tested actually provided the DNS suffix I was looking for. Here's what I came up with.

public static string GetFqdn()
{
    var networkInterfaces = NetworkInterface.GetAllNetworkInterfaces();
    var ipprops = networkInterfaces.First().GetIPProperties();
    var suffix = ipprops.DnsSuffix;
    return $"{IPGlobalProperties.GetIPGlobalProperties().HostName}.{suffix}";
}
Jon Davis
  • 6,562
  • 5
  • 43
  • 60
  • 1
    This would assume that you have only one functional network interface. Most people have a LAN, one or more Wifi and even a VPN interface. That makes "First()" a very questionable solution. – Marcel Grüger Sep 19 '22 at 06:17
0

I've used this approach:

private static string GetLocalhostFQDN()
{
    var ipProperties = IPGlobalProperties.GetIPGlobalProperties();
    return $"{ipProperties.HostName}.{ipProperties.DomainName}";
}
isxaker
  • 8,446
  • 12
  • 60
  • 87
0

My collection of methods to handle all cases around FQ Hostname / Hostname / NetBIOS Machinename / DomainName

    /// <summary>
    /// Get the full qualified hostname
    /// </summary>
    /// <param name="throwOnMissingDomainName"></param>
    /// <returns></returns>
    public static string GetMachineFQHostName(bool throwOnMissingDomainName = false)
    {
        string domainName = GetMachineFQDomainName();
        string hostName = GetMachineHostName();

        if (string.IsNullOrEmpty(domainName) && throwOnMissingDomainName) throw new Exception($"Missing domain name on machine: { hostName }");
        else if (string.IsNullOrEmpty(domainName)) return hostName;
        //<----------

        return $"{ hostName }.{ domainName }";
    }


    /// <summary>
    /// Get the NetBIOS name of the local machine
    /// </summary>
    /// <returns></returns>
    public static string GetMachineName()
    {
        return Environment.MachineName;
    }

    /// <summary>
    /// Get the Hostname from the local machine which differs from the NetBIOS name when 
    /// longer than 15 characters
    /// </summary>
    /// <returns></returns>
    public static string GetMachineHostName()
    {
        /// I have been told that GetHostName() may return the FQName. Never seen that, but better safe than sorry ....
        string hostNameRaw = System.Net.Dns.GetHostName();
        return hostNameRaw.Split('.')[0];
    }

    /// <summary>
    /// Check if hostname and NetBIOS name are equal
    /// </summary>
    /// <returns></returns>
    public static bool AreHostNameAndNetBIOSNameEqual()
    {
        return GetMachineHostName().Equals(GetMachineName(), StringComparison.OrdinalIgnoreCase);
    }

    /// <summary>
    /// Get the domain name without the hostname
    /// </summary>
    /// <returns></returns>
    public static string GetMachineFQDomainName()
    {
        return IPGlobalProperties.GetIPGlobalProperties().DomainName;
    }
marsh-wiggle
  • 2,508
  • 3
  • 35
  • 52
-9

If you want to tidy it up, and handle exceptions, try this:

public static string GetLocalhostFQDN()
        {
            string domainName = string.Empty;
            try
            {
                domainName = NetworkInformation.IPGlobalProperties.GetIPGlobalProperties().DomainName;
            }
            catch
            {
            }
            string fqdn = "localhost";
            try
            {
                fqdn = System.Net.Dns.GetHostName();
                if (!string.IsNullOrEmpty(domainName))
                {
                    if (!fqdn.ToLowerInvariant().EndsWith("." + domainName.ToLowerInvariant()))
                    {
                        fqdn += "." + domainName;
                    }
                }
            }
            catch
            {
            }
            return fqdn;
        }
Roger Willcocks
  • 1,649
  • 13
  • 27