I was futzing around with SMO recently, and wanted to grab information around the read-routing list in an Availability Group. Things went fine for 2012 and 2014, but when it came to SQL Server 2016 I ran into a problem.
The read-routing property in SMO is a string collection (reference https://msdn.microsoft.com/en-us/library/microsoft.sqlserver.management.smo.availabilityreplica.readonlyroutinglist.aspx), which is fine for 2012/4, but SQL Server 2016 introduced the idea of load-balanced read-routing. When used this provide you with the option of having multiple read-only replicas which can handle traffic, and are load-balanced (it only uses a basic round-robin algorithm, but that’s a lot better than the single replica option that exists in the earlier versions). In order to correctly know how read-routing is configured you need to know what replicas are in a load-balanced group. SMO does not provide you with the ability to get at this information (nor does it give you the chance to configure read-routing in a load-balanced scenario), as it is a basic collection, and has no further property information around it.
I’ve created a Connect item (Gathering Read Routing information using SMO is inaccurate in SQL 2016) to try and get MS to look into this, and maybe provide a fix, please upvote if you can.
If you want to try this for yourself you can use the C# below, try it against the lower versions, and then on a load-balanced 2016 configuration. While it’s still possible to get this data from TSQL I find it annoying that the server management objects that are specifically written to deal with this stuff don’t do the job.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Microsoft.SqlServer.Management.Smo; using Microsoft.SqlServer.Management.Common; namespace SmoTesting { class Program { static void Main(string[] args) { Console.WriteLine("Enter the servername"); string connectServer = Console.ReadLine(); Console.WriteLine("Enter the AG name"); string agName = Console.ReadLine(); Server srv = new Server(); try { srv = new Server(connectServer); srv.ConnectionContext.StatementTimeout = 60; //timeout after 60 seconds running the query foreach (AvailabilityGroup ag in srv.AvailabilityGroups) { if (ag.Name == agName) { ag.PrimaryReplicaServerName.ToString()); foreach (AvailabilityReplica ar in ag.AvailabilityReplicas) { if (ar.Name.ToString() == "connectServer") { foreach (Object obj in ar.ReadonlyRoutingList) { Console.WriteLine(" {0}", obj); } } } } } } catch (Exception ex) { Console.WriteLine(ex.InnerException.ToString()); } finally { srv.ConnectionContext.Disconnect(); } Console.WriteLine("press a key"); Console.Read(); } } }