How can I determine installed SQL Server instances and their versions? - sql-server

I'm trying to determine what instances of sql server/sql express I have installed (either manually or programmatically) but all of the examples are telling me to run a SQL query to determine this which assumes I'm already connected to a particular instance.

At a command line:
SQLCMD -L
or
OSQL -L
(Note: must be a capital L)
This will list all the sql servers installed on your network. There are configuration options you can set to prevent a SQL Server from showing in the list. To do this...
At command line:
svrnetcn
In the enabled protocols list, select 'TCP/IP', then click properties. There is a check box for 'Hide server'.

You could query this registry value to get the SQL version directly:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\90\Tools\ClientSetup\CurrentVersion
Alternatively you can query your instance name and then use sqlcmd with your instance name that you would like:
To see your instance name:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names
Then execute this:
SELECT SERVERPROPERTY('productversion'), SERVERPROPERTY ('productlevel'), SERVERPROPERTY ('edition')
If you are using C++ you can use this code to get the registry information.

All of the instances installed should show up in the Services Snap-In in the Microsoft Management Console. To get the instance names, go to Start | Run | type Services.msc and look for all entries with "Sql Server (Instance Name)".

-- T-SQL Query to find list of Instances Installed on a machine
DECLARE #GetInstances TABLE
( Value nvarchar(100),
InstanceNames nvarchar(100),
Data nvarchar(100))
Insert into #GetInstances
EXECUTE xp_regread
#rootkey = 'HKEY_LOCAL_MACHINE',
#key = 'SOFTWARE\Microsoft\Microsoft SQL Server',
#value_name = 'InstalledInstances'
Select InstanceNames from #GetInstances

I know this thread is a bit old, but I came across this thread before I found the answer I was looking for and thought I'd share. If you are using SQLExpress (or localdb) there is a simpler way to find your instance names.
At a command line type:
> sqllocaldb i
This will list the instance names you have installed locally. So your full server name should include (localdb)\ in front of the instance name to connect. Also, sqllocaldb allows you to create new instances or delete them as well as configure them. See: SqlLocalDB Utility.

If you just want to see what's installed on the machine you're currently logged in to, I think the most straightforward manual process is to just open the SQL Server Configuration Manager (from the Start menu), which displays all the SQL Services (and only SQL services) on that hardware (running or not). This assumes SQL Server 2005, or greater; dotnetengineer's recommendation to use the Services Management Console will show you all services, and should always be available (if you're running earlier versions of SQL Server, for example).
If you're looking for a broader discovery process, however, you might consider third party tools such as SQLRecon and SQLPing, which will scan your network and build a report of all SQL Service instances found on any server to which they have access. It's been a while since I've used tools like this, but I was surprised at what they found (namely, a handful of instances that I didn't know existed). YMMV. You might Google for details, but I believe this page has the relevant downloads: http://www.sqlsecurity.com/Tools/FreeTools/tabid/65/Default.aspx

SQL Server permits applications to find SQL Server instances within the current network. The SqlDataSourceEnumerator class exposes this information to the application developer, providing a DataTable containing information about all the visible servers. This returned table contains a list of server instances available on the network that matches the list provided when a user attempts to create a new connection, and expands the drop-down list containing all the available servers on the Connection Properties dialog box. The results displayed are not always complete.
In order to retrieve the table containing information about the available SQL Server instances, you must first retrieve an enumerator, using the shared/static Instance property:
using System.Data.Sql;
class Program
{
static void Main()
{
// Retrieve the enumerator instance and then the data.
SqlDataSourceEnumerator instance =
SqlDataSourceEnumerator.Instance;
System.Data.DataTable table = instance.GetDataSources();
// Display the contents of the table.
DisplayData(table);
Console.WriteLine("Press any key to continue.");
Console.ReadKey();
}
private static void DisplayData(System.Data.DataTable table)
{
foreach (System.Data.DataRow row in table.Rows)
{
foreach (System.Data.DataColumn col in table.Columns)
{
Console.WriteLine("{0} = {1}", col.ColumnName, row[col]);
}
Console.WriteLine("============================");
}
}
}
from msdn http://msdn.microsoft.com/en-us/library/a6t1z9x2(v=vs.80).aspx

One more option would be to run SQLSERVER discovery report..go to installation media of sqlserver and double click setup.exe
and in the next screen,go to tools and click discovery report as shown below
This will show you all the instances present along with entire features..below is a snapshot on my pc

SQL Server Browser Service http://msdn.microsoft.com/en-us/library/ms181087.aspx

This query should get you the server name and instance name :
SELECT ##SERVERNAME, ##SERVICENAME

If you are interested in determining this in a script, you can try the following:
sc \\server_name query | grep MSSQL
Note: grep is part of gnuwin32 tools

From Windows command-line, type:
SC \\server_name query | find /I "SQL Server ("
Where "server_name" is the name of any remote server on which you wish to display the SQL instances.
This requires enough permissions of course.

I had the same problem. The "osql -L" command displayed only a list of servers but without instance names (only the instance of my local SQL Sever was displayed).
With Wireshark, sqlbrowser.exe (which can by found in the shared folder of your SQL installation) I found a solution for my problem.
The local instance is resolved by registry entry. The remote instances are resolved by UDP broadcast (port 1434) and SMB.
Use "sqlbrowser.exe -c" to list the requests.
My configuration uses 1 physical and 3 virtual network adapters.
If I used the "osql -L" command the sqlbrowser displayed a request from one of the virtual adaptors (which is in another network segment), instead of the physical one.
osql selects the adpater by its metric. You can see the metric with command "route print".
For my configuration the routing table showed a lower metric for teh virtual adapter then for the physical. So I changed the interface metric in the network properties by deselecting automatic metric in the advanced network settings.
osql now uses the physical adapter.

The commands OSQL -L and SQLCMD -L will show you all instances on the network.
If you want to have a list of all instances on the server and doesn't feel like doing scripting or programming, do this:
Start Windows Task Manager
Tick the checkbox "Show processes from all users" or equivalent
Sort the processes by "Image Name"
Locate all sqlsrvr.exe images
The instances should be listed in the "User Name" column as MSSQL$INSTANCE_NAME.
And I went from thinking the poor server was running 63 instances to realizing it was running three (out of which one was behaving like a total bully with the CPU load...)

I just installed Sql server 2008, but i was unable to connect to any database instances.
The commands #G Mastros posted listed no active instances.
So i looked in services and found that the SQL server agent was disabled. I fixed it by setting it to automatic and then starting it.

I had this same issue when I was assessing 100+ servers, I had a script written in C# to browse the service names consist of SQL. When instances installed on the server, SQL Server adds a service for each instance with service name. It may vary for different versions like 2000 to 2008 but for sure there is a service with instance name.
I take the service name and obtain instance name from the service name. Here is the sample code used with WMI Query Result:
if (ServiceData.DisplayName == "MSSQLSERVER" || ServiceData.DisplayName == "SQL Server (MSSQLSERVER)")
{
InstanceData.Name = "DEFAULT";
InstanceData.ConnectionName = CurrentMachine.Name;
CurrentMachine.ListOfInstances.Add(InstanceData);
}
else
if (ServiceData.DisplayName.Contains("SQL Server (") == true)
{
InstanceData.Name = ServiceData.DisplayName.Substring(
ServiceData.DisplayName.IndexOf("(") + 1,
ServiceData.DisplayName.IndexOf(")") - ServiceData.DisplayName.IndexOf("(") - 1
);
InstanceData.ConnectionName = CurrentMachine.Name + "\\" + InstanceData.Name;
CurrentMachine.ListOfInstances.Add(InstanceData);
}
else
if (ServiceData.DisplayName.Contains("MSSQL$") == true)
{
InstanceData.Name = ServiceData.DisplayName.Substring(
ServiceData.DisplayName.IndexOf("$") + 1,
ServiceData.DisplayName.Length - ServiceData.DisplayName.IndexOf("$") - 1
);
InstanceData.ConnectionName = CurrentMachine.Name + "\\" + InstanceData.Name;
CurrentMachine.ListOfInstances.Add(InstanceData);
}

Will get the instances of SQL server
reg query "HKLM\Software\Microsoft\Microsoft SQL Server\Instance Names\SQL"
or Use
SQLCMD -L

Here is a simple method:
go to
Start then
Programs then
Microsoft SQL Server 2005 then
Configuration Tools then
SQL Server Configuration Manager then
SQL Server 2005 Network Configuration then
Here you can locate all the instance installed onto your machine.

I know its an old post but I found a nice solution with PoweShell where you can find SQL instances installed on local or a remote machine including the version and also be extend get other properties.
$MachineName = ‘.’ # Default local computer Replace . with server name for a remote computer
$reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey(‘LocalMachine’, $MachineName)
$regKey= $reg.OpenSubKey("SOFTWARE\\Microsoft\\Microsoft SQL Server\\Instance Names\\SQL" )
$values = $regkey.GetValueNames()
$values | ForEach-Object {$value = $_ ; $inst = $regKey.GetValue($value);
$path = "SOFTWARE\\Microsoft\\Microsoft SQL Server\\"+$inst+"\\MSSQLServer\\"+"CurrentVersion";
#write-host $path;
$version = $reg.OpenSubKey($path).GetValue("CurrentVersion");
write-host "Instance" $value;
write-host "Version" $version}

If your within SSMS you might find it easier to use:
SELECT ##Version

Related

Check if a named SQL Server Instance is running on local computer or not

You might find the question duplicate to these 2 links (Link1 and Link2) but they haven't been answered correctly. Let me brief you the question what i really want.
Looking For
I am looking for a way through which we can check if the provided SQL Instance Name is locally available or is residing on another remote computer.
My local SQL Server Instance name is Office-PC\SQLEXPRESS
Solutions i found which didn't work
1) Source : When i use the below code it says remote while the specified instance is present local.
SELECT Case when HOST_NAME()=SERVERPROPERTY('Office-PC\SQLEXPRESS') then 'local' else 'remote' end
2) I tried using the below code suggested in many comments on different websites. But it is showing incorrect output.
print HOST_NAME() //OUTPUT : Office-PC
print ##SERVERNAME //OUTPUT : HOME\SQLEXPRESS
3) Some people suggested to use the below command to get instance name which works perfectly but it doesn't tell us which of the instance is locally available.
SQLCMD -L
4) I also read somewhere (can't find the link) that we can get the Instance name from Registry itself.
That is all i could find.
If anyone has any other ways to find if the provided named SQL Instance is locally available, then please let me know.
This is a little more complicated than I'd like, but HOST_NAME() or the server machine name aren't reliable, the following should do:
SELECT CASE
WHEN client_net_address IN ('<local machine>', '<named pipe>', local_net_address) THEN 'local'
ELSE 'remote'
END AS [ConnectionType]
FROM sys.dm_exec_connections
-- The parent_connection_id check covers MARS
WHERE session_id = ##SPID AND parent_connection_id IS NULL
Disclaimer: not thoroughly tested with all possible transports. This works against local memory connections, LocalDB instances and TCP/IP connections, but it may not work correctly if you use the (rare) remote named pipes or VIA transports. These are disabled by default.
You can use SERVERPROPERTY like this:
SELECT CASE WHEN HOST_NAME()=SERVERPROPERTY('MachineName') THEN 'local' ELSE 'remote' END
MachineName
Windows computer name on which the server instance is running.
For a clustered instance, an instance of SQL Server running on a
virtual server on Microsoft Cluster Service, it returns the name of
the virtual server.

How to Remove a Ghost Server in Web Farm After Migrating a Reporting Services Installation?

Just followed the steps in https://msdn.microsoft.com/en-us/library/ms143724.aspx to migrate a Reporting Services installation onto a new server (from and to SQL 2012 Standard Edition)
But when I'm ready to verify my deployment using the Report Manager web interface I get the error:
The feature: "Scale-out deployment" is not supported in this edition of Reporting Services. (rsOperationNotSupported)
Indeed when I go back to the Reporting Services Configuration manager, under Scale-out Deployment I have 2 servers, the one on the local server (new machine) and a reference to the old Server that has a different name. Problem is when I try to remove it tells me the task has failed:
Microsoft.ReportingServices.WmiProvider.WMIProviderException: Unable to connect to the Report Server . ---> System.Runtime.InteropServices.COMException (0x800706BA): The RPC server is unavailable
I can understand why it's unavailable as it is on a different network all together. so my question is, how can I get rid of it so everything can finally work?
Found it. The way to remove the ghost server is to connect to the ReportServer database, and remove the old server from the dbo.Keys table.
After a restart of Reporting Services, the old server isn't in the list anymore.
USE ReportServer
go
select * from keys
--for safety added to the delete ghost machine if no recent executions in last 30 days.
delete from keys
where MachineName = 'YourGhostServer' --replace with your old server name, if multiple run one by one.
and MachineName not in (select substring(InstanceName,0,(charindex('\',InstanceName,0)))
from ExecutionLog
where timestart>getdate()-30
group by InstanceName)
CAREFUL, run the first part only with the select, analyze the output then copy the specific machine name value (old server name) you wish to delete into the where clause of the delete statement, replacing YourGhostServer verbiage.
Note, the Keys table may have legitimate machines that are network reachable and online. You can verify this by simply pinging them or checking if they run the SSRS Service, don't just simply delete from the table a server that's actually online, instead use the Report Server Manager to remove a Server that's online.
Deleting from the Keys table should only be done if the old machine is truly unreachable or has been decommissioned. At least, that's what I would do in my case. :)

finding the correct connection string for a local SQL instance

I'm trying to build a connection string for a test environment that will connect to the local SQL Server instance on different machines. The purpose of this is so that a developer can checkout the code from TFS, build it, and run the testcases, connecting to his local DB. The problem is that different developer's machines may have different SQL Server setups. In particular, some may be running the full server, others may be running SQL Server Express.
I'm trying to right a utility routine that will take template connection string (e.g., Data Source=(local); Initial Catalog= myDB; Integrated Security=SSPI;) and modify the Data Source to work with the local server.
I've tried using SmoApplication.EnumAvailableServers() (returns an empty table, regardless of whether I user true or false parameters), and SqlDataSourceEnumerator.GetDataSources() (returns 2888 servers from the network, but none on the local machine), SQLCMD -L (returns nothing).
Any suggestions?
In the alternative, is there an easy way to tell whether a particular connection string will connect to a server (without waiting for it to timeout if it doesn't). If I could find the answer to that, I could try the likely suspects until I got one to work.
you might try to get the connection string as following:
Create a new blank file and name it test.udl.
Double click on it, and a "Data Link Properties" dialog should appear.
On "Providers" tab, select "Microsoft OLE DB Provider for SQL Server" or "SQL Native Client"
On "Connections" tab, try various settings and use the "Test Connection" button to test them. Click "Ok" when it works.
Open the test.udl file in Notepad and copy the line that starts with "Provider=" into your Web.config "ConnectionString" value, BUT delete the little part that says "Provider=SQLNCLI.1;"
If you want each developer to work with their own local SQL server, then the ADO connection string should have the Data Source set to localhost
... ; Data Source=localhost; ...
Additionally, to get a list of current servers, go to the command line and run
osql -L
You can look in the registry to find all local SQL Server instances. This key contains the list: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL.
Each named instance will have a value in this key. For named instances the name of the value is the same as the name of the instance. For the default instance the value will be named MSSQLSERVER.
This will do the trick:
Data Source=.\SQLEXPRESS

Querying for SQL Servers in an Inno-setup project

I'm creating a setup using Inno-setup.
During the setup process, a SQL Server database has to be created. I want to give the user the ability to select an existing SQL Server instance (if one exists), where the database has to be created.
So, what I want to do in the setup, is to query the network (and the local machine) for SQL Server instances.Furthermore, when the user has selected an instance, I want to verify if there exists a database on that instance which has a specific name.
Anybody who knows how I can do this ? Or maybe someone could give me some pointers in the good direction?
Inno Setup supports the call of external DLL functions, so you should write a suitable helper DLL. Managed .net DLLs can only be used via a COM interface, otherwise you need an unmanaged DLL.
Valid calling conventions are: 'stdcall' (the default), 'cdecl', 'pascal' and 'register'.
Try the following native .Net library call:
using System.Data.Sql;
var instance = SqlDataSourceEnumerator.Instance;
DataTable dataTable = instance.GetDataSources();
The resultant datatable contains the following columns:
ServerName
Name of the server.
InstanceName
Name of the server instance. Blank if the server is running as the default instance.
IsClustered
Indicates whether the server is part of a cluster.
Version
Version of the server (8.00.x for SQL Server 2000, and 9.00.x for SQL Server 2005).

How can I get the name of the database server from within a stored procedure?

I'm making complete connection strings inside my procedure and would like to inject the name of the database server in them. Is there any way that I can detect the name from inside or am I doomed to passing it in?
Use SERVERPROPERTY:
SERVERPROPERTY('MachineName'): name of the SQL Server host name, cluster aware
SERVERPROPERTY('ComputerNamePhysicalNetBIOS'): name of physical machine name. In a cluster, is the name of the current active node. On a standalone instalation, is identical with MachineName
SERVERPROPERTY('InstanceName'): name of the current SQL Server instance. NULL for default.
One thing I'd recomend against is the dreaded ##SERVERNAME. This property is notorious for getting out of sync with reality after a machine rename. I've seen way too many apps burned by this problem to place any trust on it. The correct rename procedure is in BOL, but few use it properly: How to: Rename a Computer that Hosts a Stand-Alone Instance of SQL Server.
So for MS SQL Server you could:
SELECT ##SERVERNAME
For MySQL, it's
SELECT variable_value as servername
FROM information_schema.global_variables
WHERE variable_name = 'hostname';
For Oracle, its:
SELECT global_name FROM global_name

Resources