Smo does not show 2008 SQL Server instances when 2005 instances exist - sql-server

I am trying to enumerate all SQL Server instances installed on a local machine. I am using SmoApplication.EnumAvailableSqlServers(true). However, only SQL Server Express 2005 instances are shown. Default 2008 instance is not shown at all!
I tried 2 other solutions with SqlServerRegistrations.EnumRegisteredServers() and SqlDataSourceEnumerator.Instance.GetDataSources() but they do not work either.
There is another question regarding this (Can't enumerate SQL Server 2008 Registered Servers with SMO) but it unfortunately has no answer.

Found the solution to your problem here
Solution: Explicitly set the ProviderArchitecture property to the architecture of the target SQL Server.
If you do not explicitly set the ProviderArchitecture property, it will assume that of the running process. If the host process of your application does not match the architecture of the installed version of SQL Server on the target server, the ServerInstances collection will be empty. This is due to the separate x86 and x64 WMI providers and how SQL Server registers instances.
Try
Dim objManagedComputer As New ManagedComputer("target_servername")
objManagedComputer.ConnectionSettings.ProviderArchitecture = ProviderArchitecture.Use64bit
Dim objServerInstance As ServerInstance
For Each objServerInstance In objManagedComputer.ServerInstances
MsgBox(objServerInstance.Name)
Next
Catch ex As Exception
MsgBox(ex.Message)
End Try

Here's another alternative you could try using the ManagedComputer Class (Namespace: Microsoft.SqlServer.Management.Smo.Wmi).
ManagedComputer mc = new ManagedComputer();
foreach (ServerInstance si in mc.ServerInstances)
{
Console.WriteLine(si.Name);
}

Related

ADODB Command Parameters Refresh doesn't retrieve parameters

I have an old web application, built with VBScript on an IIS6 Server with a SQL Server 2008 database. It is in the processed of being moved to a new server, on IIS8.
Every queries in the app work with stored procedures, with which we never had a problem. But on the new server, it doesn't seem to work. I found it it's because the Command.Parameters.Refresh doesn't return the parameters properly.
Consider this code:
Set cmd = Server.CreateObject("ADODB.Command")
cmd.ActiveConnection = conn
cmd.CommandType = 4
cmd.CommandText = v_strSpName
cmd.CommandTimeout = 0
cmd.Parameters.Refresh
For i = LBound(v_arrParameters) To UBound(v_arrParameters)
If m_bReplaceEmptyToNull Then
v_arrParameters(i)(1) = ReplaceEmpty(v_arrParameters(i)(1))
End If
cmd.Parameters(v_arrParameters(i)(0)).value = v_arrParameters(i)(1)
Next
Everything in v_arrParameters exists, but I tried iterating in Parameters.name after the refresh, the parameters are not returned (but they are on the production server).
Also worth noting, the SQL Profiler does receive the query and return the parameters:
exec [Database]..sp_procedure_params_rowset N'get_company',1,N'dbo',NULL
According to this page, it is a known issue, I just want to make sure it doesn't come from this problem, and find a solution or an alternative that doesn't imply a full rewriting of the application.
Also, no I can not update the SQL Server version, switch to VB.NET, there is always the issue that there is a client that won't pay for this problem.
So we managed to make it work this way:
Opening the Applications Pools section in IIS Manager.
Going in the Advanced Settings of the Default App Pool (its name here, maybe not for everyone, I don't know)
Setting Enable 32-bits apps to True
This is on a 64-bit Windows Server 2012 R2, with Microsoft SQL Server 2008 (SP4) - 10.0.6241.0 (X64) .

VBScript Error Trying to disable dynamic port in SQL Server

I've been trying to automate disabling dynamic ports in a new installation of SQL Server 2012 and setting a static TCP port. I can do this without an issue from the SQL Configuration Manager, but getting a script to do this is giving me more trouble. Luckily, I found someone that was looking to do the exact same thing here: MSDN Forums.
The code I'm using is the following:
Private Function setProperty ( ByVal path, ByVal value )
Set obj = GetObject(path)
errornumber = obj.SetStringValue(value)
If Not errornumber = 0 Then
WScript.Quit(errornumber)
End If
End Function
Set args = WScript.Arguments
If Not args.Count = 1 Then
WScript.Echo "ERROR: Invalid arguments"
WScript.Echo "Usage: cscript " & WScript.ScriptName & " "
WScript.Quit(255)
End If
' set TCP/IP port of SQLServer instance 'SQLSERVER_MATRIX'
setProperty "WINMGMTS:\\.\root\Microsoft\SqlServer\ComputerManagement:ServerNetworkProtocolProperty.InstanceName='SQLSERVER_MATRIX',IPAddressName='IPAll',PropertyName='TcpPort',PropertyType=1,ProtocolName='Tcp'", args(0)
' switch off dynamic ports
setProperty "WINMGMTS:\\.\root\Microsoft\SqlServer\ComputerManagement:ServerNetworkProtocolProperty.InstanceName='SQLSERVER_MATRIX',IPAddressName='IPAll',PropertyName='TcpDynamicPorts',PropertyType=1,ProtocolName='Tcp'", ""
I try running it as suggested on the site with
cscript.exe //nologo set_port_property.vbs
and get the error:
set_port_property.vbs(1,1) (null): 0x8004100E
So that's giving me a namespace error and this is where I'm stuck. It doesn't look like anyone else is having issues with this file as I've found it in multiple places, but I'm trying this on a Windows 10 computer with SQL Server 2012 and everything I found was using 2008 and at most Windows 8. There's a Scriptomatic 2.0 tool that may help, but the link on Microsoft's page is broken so I don't know where to go from here.
The error code as you point out is
WBEM_E_INVALID_NAMESPACE (0x8004100E)
The specified namespace did not exist on the server.
Which is pretty self explanatory, basically the namespace being passed is not recognised for whatever reason, usually it's just incorrectly typed but as you have already mentioned others are using this script without issue.
Couple of suggestions
This likely points to the machine, the first thing I would try is running the script on another machine to see if it can be isolated to this machine alone.
You may also want to test the health of the WMI installation using the in-built tools provided in Windows. The wbemtest.exe tool is a great little tool for testing connection to and query WMI respositories.
Stumbled on the Answer
In the process of answering this question think I may have stumbled on the answer.
Tried suggestion 2. myself to test connecting to
root\microsoft\sqlserver\computermanagement
but failed with the same error using wbemtest.exe but found I could connect to
root\microsoft\sqlserver
After a quick google found the MSDN documentation that describes"How to: Access WMI Provider for Configuration Management using WQL" pointed me in the right direction.
You see the namespaces are different for later versions of SQL Server.
SQL Server 2005
root\Microsoft\SqlServer\ComputerManagement
SQL Server 2008 R2
root\Microsoft\SqlServer\ComputerManagement10
SQL Server 2012, SQL Server 2014, SQL Server 2016#
root\Microsoft\SqlServer\ComputerManagement11
# - Possibly subject to change
After connecting to
root\Microsoft\SqlServer\ComputerManagement11
using wbemtest.exe I no longer received the error and was able to browse classes and instances.
With that in mind changing your namespace in the code should fix the issue.
' set TCP/IP port of SQLServer instance 'SQLSERVER_MATRIX'
setProperty "WINMGMTS:\\.\root\Microsoft\SqlServer\ComputerManagement11:ServerNetworkProtocolProperty.InstanceName='SQLSERVER_MATRIX',IPAddressName='IPAll',PropertyName='TcpPort',PropertyType=1,ProtocolName='Tcp'", args(0)
' switch off dynamic ports
setProperty "WINMGMTS:\\.\root\Microsoft\SqlServer\ComputerManagement11:ServerNetworkProtocolProperty.InstanceName='SQLSERVER_MATRIX',IPAddressName='IPAll',PropertyName='TcpDynamicPorts',PropertyType=1,ProtocolName='Tcp'", ""
In fact at the very bottom of that thread on MSDN someone even hints at this but for SQL Server 2008
Goozak posted in MSDN Forums - silent install with fixed tcp port
Date: Wednesday, March 17, 2010 3:13 PM
"know this is an old thread, but since this is the post I found that helped me solve my problem, I just want to add that for SQL Server 2008 Express, you need to use ComputerManagement10 :ServerNetworkProtocolProperty..."

Why only some users get the error: "Connection is busy with results for another command"

I have a Delphi Application that is connected to a SQL Server db using SDAC component from DevArt, we have 200 installations of the software and only to a customer, with some users, I notice the following error:
"Connection is busy with results for another command" = "La connessione è occupata dai risultati di un altro comando".
SQL vers.: SQL Server 2008 R2 Express with filestream full enabled
My application create both db users and SQL account logins:
creating a new user, then there aren't problems
changing user code in my application, it means that another db user and SQL account login is created, I have the error
this problem happens only with some users, not all ones
What I've already tried without luck:
deleted and re-installed database
uninstalled and re-installed SQL Server Instance
checked users/account properties in SQL Server (all ok)
If you need specific infos please tell me
------------NEW INFORMATIONS------------
I checked better all the Instance properties from Studio Management and I've noticed that CPU's are not checked (see image below).
Instead in all the other normal installations of SQL Server, I see filled checkboxes.
Could it be the problem?
I hope this help you to help me...
The "Connection is busy with results for another command" error means that there are at least two queries that use the same connection. This problem can occur if you are using one connection in several threads. To solve the problem in this case, you should have connection (the TMSConnection component) in each thread.
Also, this problem can occur if you set the TCustomMSDataSet.FetchAll property to False. When FetchAll=False, execution of such queries blocks the current session. In order to avoid blocking OLEDB creates additional session that can cause the "Connection is busy with results for another command" error. To solve the problem in this case, you should set the TMSConnection.Options.MultipleActiveResultSets property to True. The MultipleActiveResultSets property enables support for the SQL Server Multiple Active Result Sets (MARS) technology. It allows applications to have more than one pending request per connection, and, in particular, to have more than one active default result set per connection. Please note that the MultipleActiveResultSets property works only when SQL Native Client is used. Therefore, you should also set the TMSConnection.Options.Provider property to prNativeClient.
Just wanted to correct dataol's answer and say that MARS_Connection should be set to "Yes" instead of "True" to enable Multiple Active Result Sets. At least on SQL Server 2012 if you are using a DSN file:
[ODBC]
DRIVER=SQL Server Native Client 11.0
DATABASE=MYDBNAME
WSID=
Trusted_Connection=Yes
SERVER=
MARS_Connection=Yes
To provide Multiple Active Result Set (MARS) support to a SQL connection using the MSSQL driver, you must add a key called Mars_Connection and set its value to True.
#ienax_ridens, I recently encountered the same problem using the same tools (Delphi and Devart-SDAC).
In my case one specific query giving two results sets.
My TMSQuery was
If Condition= 1
begin
Select * from #TempTable1
end else
begin
-- Some more stuff
Insert INTO #TempTable2
--
--
End
Select * from TempTable1 -- here is the problem
so in case of Condition = 1 it was giving two results sets and causing "Connection is busy with results for another command"
I hope this helps you.
Edit: I realized you post is quite old, please share what you did to resolve this error
I had the same problem and solved installing the microsoft odbc driver 11 (msodbcsql) (https://www.microsoft.com/pt-br/download/confirmation.aspx?id=36434).
Check your compatibility mode i just ran into this when we moved from 2008 to 2016 db we had to set it to 2012 compatibility mode.
I had this problem when I found that my runtime DLL was in the environment path and the program folder. It was a runtime issue and nothing with the program.

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 determine installed SQL Server instances and their versions?

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

Resources