bin/projects/dbatools/dbatools/Utility/Validation.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
using System;

namespace Sqlcollaborative.Dbatools.Utility
{
    using System.Net;
    using System.Net.NetworkInformation;
    using System.Text.RegularExpressions;
    /// <summary>
    /// Provides helper methods that aid in validating stuff.
    /// </summary>
    public static class Validation
    {
        /// <summary>
        /// Tests whether a given string is the local host.
        /// Does NOT use DNS resolution, DNS aliases will NOT be recognized!
        /// </summary>
        /// <param name="Name">The name to test for being local host</param>
        /// <returns>Whether the name is localhost</returns>
        public static bool IsLocalhost(string Name)
        {
            #region Handle IP Addresses
            try
            {
                IPAddress tempAddress;
                IPAddress.TryParse(Name, out tempAddress);
                if (IPAddress.IsLoopback(tempAddress))
                    return true;

                foreach (NetworkInterface netInterface in NetworkInterface.GetAllNetworkInterfaces())
                {
                    IPInterfaceProperties ipProps = netInterface.GetIPProperties();
                    foreach (UnicastIPAddressInformation addr in ipProps.UnicastAddresses)
                    {
                        if (tempAddress.ToString() == addr.Address.ToString())
                            return true;
                    }
                }
            }
            catch { }
            #endregion Handle IP Addresses

            #region Handle Names
            try
            {
                if (Name == ".")
                    return true;
                if (Name.ToLower() == "localhost")
                    return true;
                if (Name.ToLower() == Environment.MachineName.ToLower())
                    return true;
                if (Name.ToLower() == (Environment.MachineName + "." + Environment.GetEnvironmentVariable("USERDNSDOMAIN")).ToLower())
                    return true;
            }
            catch { }
            #endregion Handle Names
            return false;
        }

        /// <summary>
        /// Tests whether a given string is a recommended instance name. Recommended names musst be legal, nbot on the ODBC list and not on the list of words likely to become reserved keywords in the future.
        /// </summary>
        /// <param name="InstanceName">The name to test. MAY contain server name, but will NOT test the server.</param>
        /// <returns>Whether the name is recommended</returns>
        public static bool IsRecommendedInstanceName(string InstanceName)
        {
            string temp;
            if (InstanceName.Split('\\').Length == 1) { temp = InstanceName; }
            else if (InstanceName.Split('\\').Length == 2) { temp = InstanceName.Split('\\')[1]; }
            else { return false; }

            if (Regex.IsMatch(temp, RegexHelper.SqlReservedKeyword, RegexOptions.IgnoreCase)) { return false; }
            if (Regex.IsMatch(temp, RegexHelper.SqlReservedKeywordFuture, RegexOptions.IgnoreCase)) { return false; }
            if (Regex.IsMatch(temp, RegexHelper.SqlReservedKeywordOdbc, RegexOptions.IgnoreCase)) { return false; }

            if (temp.ToLower() == "default") { return false; }
            if (temp.ToLower() == "mssqlserver") { return false; }

            if (!Regex.IsMatch(temp, RegexHelper.InstanceName, RegexOptions.IgnoreCase)) { return false; }

            return true;
        }

        /// <summary>
        /// Tests whether a given string is a valid target for targeting as a computer. Will first convert from idn name.
        /// </summary>
        public static bool IsValidComputerTarget(string ComputerName)
        {
            try
            {
                System.Globalization.IdnMapping mapping = new System.Globalization.IdnMapping();
                string temp = mapping.GetAscii(ComputerName);
                return Regex.IsMatch(temp, RegexHelper.ComputerTarget);
            }
            catch { return false; }
        }

        /// <summary>
        /// Tests whether a given string is a valid instance name.
        /// </summary>
        /// <param name="InstanceName">The name to test. MAY contain server name, but will NOT test the server.</param>
        /// <param name="Lenient">Setting this to true will make the validation ignore default and mssqlserver as illegal names (as they are illegal names for named instances, but legal for targeting)</param>
        /// <returns>Whether the name is legal</returns>
        public static bool IsValidInstanceName(string InstanceName, bool Lenient = false)
        {
            string temp;
            if (InstanceName.Split('\\').Length == 1) { temp = InstanceName; }
            else if (InstanceName.Split('\\').Length == 2) { temp = InstanceName.Split('\\')[1]; }
            else { return false; }

            if (Regex.IsMatch(temp, RegexHelper.SqlReservedKeyword, RegexOptions.IgnoreCase)) { return false; }

            if (!Lenient)
            {
                if (temp.ToLower() == "default") { return false; }
                if (temp.ToLower() == "mssqlserver") { return false; }
            }

            if (!Regex.IsMatch(temp, RegexHelper.InstanceName, RegexOptions.IgnoreCase)) { return false; }

            return true;
        }
    }
}