Search code examples
c#sql-serverwmisystem.management

Create SQL Server Alias Using WMI on x64


I have a small app which automatically creates necessary SQL Server Alias entries for some servers. The bulk of the code looks like this:

        private static void SetAlias(string aliasName, string server, string protocol, int? port)
        {
            var scope = new ManagementScope(@"\\.\root\Microsoft\SqlServer\ComputerManagement10");
            try
            {
                scope.Connect();

            }
            catch
            {
                scope = new ManagementScope(@"\\.\root\Microsoft\SqlServer\ComputerManagement");
            }
            var clientAlias = new ManagementClass(scope, new ManagementPath("SqlServerAlias"), null);
            clientAlias.Get();

            foreach (ManagementObject existingAlias in clientAlias.GetInstances())
            {
                existingAlias.Get();
                if (String.Equals((String)existingAlias.GetPropertyValue("AliasName"), aliasName))
                {
                    UpdateAlias(existingAlias, aliasName, server, protocol, port);
                    return;
                }
            }

            // create new
            ManagementObject newAlias = clientAlias.CreateInstance();
            UpdateAlias(newAlias, aliasName, server, protocol, port);
            newAlias.Put();
        }

        private static void UpdateAlias(ManagementObject alias, string aliasName, string server, string protocol, int? port)
        {
            alias.SetPropertyValue("AliasName", aliasName);
            alias.SetPropertyValue("ServerName", server);
            alias.SetPropertyValue("ProtocolName", protocol);
            alias.SetPropertyValue("ConnectionString", port != null ? port.ToString() : string.Empty);
        }

This correctly creates the entries I want on 32bit OS's, however on x64 OS's I need the aliases also added to the 64 bit SQL Server Client Configuration.

Any ideas how to do this?

Thanks.


Solution

  • I'll leave the registry answer in place since it's viable, but you can use the Context on the ConnectionOptions to specify the arch (an int, 32 or 64)

    A sample accessing both from 64-bit:

        static void Main(string[] args)
        {
            var options = new ConnectionOptions();
    
            if (Environment.Is64BitOperatingSystem && Environment.Is64BitProcess == false)
            {
                Console.WriteLine("Please build as AnyCPU or x64");
                return;
            }
    
            // default behavior, should be 64-bit WMI provider
            Console.WriteLine("Print 64-bit aliases");
            PrintAliases(options);
    
            // specify the 32-bit arch
            Console.WriteLine("Print 32-bit aliases");
            options.Context.Add("__ProviderArchitecture", 32);
            PrintAliases(options);
        }
    
        private static void PrintAliases(ConnectionOptions options)
        {
            var scope = new ManagementScope(@"\\.\root\Microsoft\SqlServer\ComputerManagement10", options);
            try
            {
                scope.Connect();
            }
            catch
            {
                scope = new ManagementScope(@"\\.\root\Microsoft\SqlServer\ComputerManagement");
            }
            var clientAlias = new ManagementClass(scope, new ManagementPath("SqlServerAlias"), null);
            clientAlias.Get();
    
            foreach (ManagementObject existingAlias in clientAlias.GetInstances())
            {
                existingAlias.Get();
                var propertiesToRead = new[] { "AliasName", "ServerName", "ProtocolName", "ConnectionString" };
                foreach (var propertyToRead  in propertiesToRead)
                {
                    Console.WriteLine("Property {0} = {1}", propertyToRead, existingAlias.GetPropertyValue(propertyToRead));
                }
            }
        }
    

    A sample accessing both from 32-bit (NOTE: could just force the arch to 32 and 64 regardless of process bitness, of course)

    class Program
    {
        static void Main(string[] args)
        {
            var options = new ConnectionOptions();
    
            if (Environment.Is64BitProcess)
            {
                Console.WriteLine("Please run this sample as 32-bit");
                return;
            }
    
            // default behavior, should be 32-bit WMI provider since we build as x86
            Console.WriteLine("Print 32-bit aliases");
            PrintAliases(options);
    
            // also prints 32-bit aliases
            options.Context.Add("__ProviderArchitecture", 32);
            PrintAliases(options);
    
            // specify the 64-bit arch
            if (Environment.Is64BitOperatingSystem)
            {
                Console.WriteLine("Print 64-bit aliases");
                options.Context.Add("__ProviderArchitecture", 64);
                PrintAliases(options);
            }
        }
    
        private static void PrintAliases(ConnectionOptions options)
        {
            var scope = new ManagementScope(@"\\.\root\Microsoft\SqlServer\ComputerManagement10", options);
            try
            {
                scope.Connect();
            }
            catch
            {
                scope = new ManagementScope(@"\\.\root\Microsoft\SqlServer\ComputerManagement");
            }
            var clientAlias = new ManagementClass(scope, new ManagementPath("SqlServerAlias"), null);
            clientAlias.Get();
    
            foreach (ManagementObject existingAlias in clientAlias.GetInstances())
            {
                existingAlias.Get();
                var propertiesToRead = new[] { "AliasName", "ServerName", "ProtocolName", "ConnectionString" };
                foreach (var propertyToRead  in propertiesToRead)
                {
                    Console.WriteLine("Property {0} = {1}", propertyToRead, existingAlias.GetPropertyValue(propertyToRead));
                }
            }
        }