SQL Server 2014 Database Discovery

Microsoft.SQLServer.2014.DBDiscovery (DataSourceModuleType)

This module type is used to discover instances of Microsoft SQL Server 2014 Databases. The module connects to SQL Server and discovers all databases together with properties.

Element properties:

TypeDataSourceModuleType
IsolationAny
AccessibilityInternal
RunAsMicrosoft.SQLServer.2014.SQLDiscoveryAccount
OutputTypeSystem.Discovery.Data

Member Modules:

ID Module Type TypeId RunAs 
DS DataSource Microsoft.Windows.TimedScript.DiscoveryProvider Default

Overrideable Parameters:

IDParameterTypeSelectorDisplay NameDescription
IntervalSecondsint$Config/IntervalSeconds$Interval (seconds)The recurring interval of time in seconds in which to run the workflow.
SyncTimestring$Config/SyncTime$Synchronization TimeThe synchronization time specified by using a 24-hour format. May be omitted.
ExcludeListstring$Config/ExcludeList$Exclude ListA comma-separated list of database names that should be excluded from discovery. You can use the wildcard * to exclude all instances.
TimeoutSecondsint$Config/TimeoutSeconds$Timeout (seconds)Specifies the time the workflow is allowed to run before being closed and marked as failed.

Source Code:

<DataSourceModuleType ID="Microsoft.SQLServer.2014.DBDiscovery" Accessibility="Internal" RunAs="Microsoft.SQLServer.2014.SQLDiscoveryAccount">
<Configuration>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="IntervalSeconds" type="xsd:integer"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="SyncTime" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="ComputerID" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="ComputerName" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="SQLConnectionString" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="SQLInstanceName" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="ExcludeList" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="TimeoutSeconds" type="xsd:int"/>
</Configuration>
<OverrideableParameters>
<OverrideableParameter ID="IntervalSeconds" ParameterType="int" Selector="$Config/IntervalSeconds$"/>
<OverrideableParameter ID="SyncTime" ParameterType="string" Selector="$Config/SyncTime$"/>
<OverrideableParameter ID="ExcludeList" ParameterType="string" Selector="$Config/ExcludeList$"/>
<OverrideableParameter ID="TimeoutSeconds" ParameterType="int" Selector="$Config/TimeoutSeconds$"/>
</OverrideableParameters>
<ModuleImplementation>
<Composite>
<MemberModules>
<DataSource ID="DS" TypeID="Windows!Microsoft.Windows.TimedScript.DiscoveryProvider">
<IntervalSeconds>$Config/IntervalSeconds$</IntervalSeconds>
<SyncTime>$Config/SyncTime$</SyncTime>
<ScriptName>DiscoverSQL2014DB.vbs</ScriptName>
<Arguments>$MPElement$ $Target/Id$ $Config/ComputerID$ $Config/ComputerName$ $Config/SQLConnectionString$ $Config/SQLInstanceName$ "Exclude:$Config/ExcludeList$" $Target/Property[Type="Microsoft.SQLServer.2014.DBEngine"]/TcpPort$</Arguments>
<ScriptBody><Script>'#Include File:Initialize.vbs

Option Explicit
SetLocale("en-us")

Function Quit()
WScript.Quit()
End Function

Function IsValidObject(ByVal oObject)
IsValidObject = False

If IsObject(oObject) Then
If Not oObject Is Nothing Then
IsValidObject = True
End If
End If
End Function

Function MomCreateObject(ByVal sProgramId)
Dim oError
Set oError = New Error

On Error Resume Next
Set MomCreateObject = CreateObject(sProgramId)
oError.Save
On Error GoTo 0

If oError.Number &lt;&gt; 0 Then ThrowScriptError "Unable to create automation object '" &amp; sProgramId &amp; "'", oError
End Function
'#Include File:SQL2014Constants.vbs

Const SQL_VERSION = "2014"
Const SQL_VERSION_NUMBER = "12"
Const SQL_WMI_NAMESPACE = "ComputerManagement12"

Const SQL_FULLTEXTSEARCH_SERVICENAME = "MSSQLFDLauncher"
Const SQL_FULLTEXTSEARCH_SERVICECLUSTERNAME = "SQL Full-text Filter Daemon Launcher"

Const SQL_DBENGINE_CLASS = "$MPElement[Name='Microsoft.SQLServer.2014.DBEngine']$"
Const SQL_DATABASE_CLASS = "$MPElement[Name='Microsoft.SQLServer.2014.Database']$"
Const SQL_AGENTJOB_CLASS = "$MPElement[Name='Microsoft.SQLServer.2014.AgentJob']$"
Const SQL_RESOURCEPOOLGROUP_CLASS = "$MPElement[Name='Microsoft.SQLServer.2014.ResourcePoolGroup']$"

Const SQL_RESOURCEPOOL_CLASS = "$MPElement[Name='Microsoft.SQLServer.2014.ResourcePool']$"
Const SQL_DEFAULTPOOL_CLASS = "$MPElement[Name='Microsoft.SQLServer.2014.DefaultPool']$"
Const SQL_INTERNALPOOL_CLASS = "$MPElement[Name='Microsoft.SQLServer.2014.InternalPool']$"
Const SQL_DEDICATED_CLASS = "$MPElement[Name='Microsoft.SQLServer.2014.UserDefinedPool']$"

Const SQL_DATABASE_ERROR_USER_POLICY_CLASS = "$MPElement[Name='Microsoft.SQLServer.2014.DatabaseErrorUserPolicy']$"
Const SQL_DATABASE_WARNING_USER_POLICY_CLASS = "$MPElement[Name='Microsoft.SQLServer.2014.DatabaseWarningUserPolicy']$"
Const SQL_USERPOLICY_DEFAULT_CATEGORY_NAME = "&lt;Default&gt;"


Const SQL_DATABASE_REFERENCES_APPLICATION_POOL = "$MPElement[Name='Microsoft.SQLServer.2014.RelationshipType.DatabaseReferencesUserResourcePool']$"









'#Include File:Error.vbs

Class Error
Private m_lNumber
Private m_sSource
Private m_sDescription
Private m_sHelpContext
Private m_sHelpFile

Public Sub Save()
m_lNumber = Err.Number
m_sSource = Err.Source
m_sDescription = Err.Description
m_sHelpContext = Err.HelpContext
m_sHelpFile = Err.HelpFile
End Sub

Public Sub Raise()
Err.Raise m_lNumber, m_sSource, m_sDescription, m_sHelpFile, m_sHelpContext
End Sub

Public Sub Clear()
m_lNumber = 0
m_sSource = ""
m_sDescription = ""
m_sHelpContext = ""
m_sHelpFile = ""
End Sub

Public Default Property Get Number()
Number = m_lNumber
End Property
Public Property Get Source()
Source = m_sSource
End Property
Public Property Get Description()
Description = m_sDescription
End Property
Public Property Get HelpContext()
HelpContext = m_sHelpContext
End Property
Public Property Get HelpFile()
HelpFile = m_sHelpFile
End Property
End Class

Function ThrowScriptErrorNoAbort(ByVal sMessage, ByVal oErr)
On Error Resume Next
Dim oAPITemp
Set oAPITemp = MOMCreateObject("MOM.ScriptAPI")
oAPITemp.LogScriptEvent WScript.ScriptName, 4201, 1, sMessage &amp; ". " &amp; oErr.Description
End Function

Function ThrowScriptError(Byval sMessage, ByVal oErr)
On Error Resume Next
ThrowScriptErrorNoAbort sMessage, oErr
Quit()
End Function

Sub HandleError(customMessage)
Dim localLogger
If Not (Err.number = 0) Then
Set localLogger = new ScriptLogger
localLogger.LogFormattedError(customMessage)
Wscript.Quit 0
End If
End Sub

Function HandleErrorContinue(customMessage)
Dim localLogger
HandleErrorContinue = False
If Not (Err.number = 0) Then
Set localLogger = new ScriptLogger
localLogger.LogFormattedError(customMessage)
Err.Clear
HandleErrorContinue = True
End If
End Function

'#Include File:ConnectionString.vbs

Function BuildConnectionString(strServer, strDatabase)
ON ERROR RESUME NEXT
Err.Clear

Dim dataSource
dataSource = BuildServerName(strServer, "")
BuildConnectionString = "Data Source=" &amp; EscapeConnStringValue(dataSource) &amp; ";Initial Catalog=" &amp; EscapeConnStringValue(strDatabase) &amp; ";Integrated Security=SSPI"
End Function

Function BuildConnectionStringWithPort(ByVal strServer, ByVal strDatabase, ByVal tcpPort)
ON ERROR RESUME NEXT
Err.Clear

Dim dataSource
dataSource = strServer
If ((tcpPort &lt;&gt; "0") And (tcpPort &lt;&gt; "")) Then
dataSource = dataSource &amp; "," &amp; tcpPort
End If
BuildConnectionStringWithPort = "Data Source=" &amp; EscapeConnStringValue(dataSource) &amp; ";Initial Catalog=" &amp; EscapeConnStringValue(strDatabase) &amp; ";Integrated Security=SSPI"
End Function

' This function should be used to escape Connection String keywords.
Function EscapeConnStringValue (ByVal strValue)
ON ERROR RESUME NEXT
Err.Clear

EscapeConnStringValue = """" + Replace(strValue, """", """""") + """"
End Function

Function EscapeWQLString (ByVal strValue)
ON ERROR RESUME NEXT
Err.Clear

EscapeWQLString = Replace(strValue, "'", "\'")
End Function

Function GetTcpPort (ByVal strServer)
ON ERROR RESUME NEXT
Err.Clear

Dim tcpPort
tcpPort = ""

Call BuildServerName(strServer, tcpPort)

GetTcpPort = tcpPort

End Function

Function BuildServerName(ByVal strServer, ByRef tcp)
ON ERROR RESUME NEXT
Err.Clear

Dim pathArray, instanceName, computerName, ip, serverName
Dim oWMI, oQuery

ip= ""

pathArray = Split(strServer, "\")
computerName = pathArray(0)
instanceName = "MSSQLSERVER"
if (pathArray.Count &gt; 1) Then
instanceName = pathArray(1)
End If

serverName = strServer

Set oWMI = GetObject("winmgmts:\\" &amp; computerName &amp; "\root\Microsoft\SqlServer\ComputerManagement12")
Set oQuery = oWMI.ExecQuery("SELECT * FROM ServerNetworkProtocolProperty WHERE ProtocolName = 'Tcp' AND InstanceName = '"&amp; EscapeWQLString(instanceName) &amp;"' AND PropertyName = 'ListenOnAllIPs'")

If oQuery.Count &gt;0 Then
Dim isListenAll
Set isListenAll = oQuery.ItemIndex(0)
If(isListenAll.PropertyNumVal = 1) Then
Set oQuery = oWMI.ExecQuery("SELECT * FROM ServerNetworkProtocolProperty WHERE ProtocolName = 'Tcp' AND InstanceName = '"&amp; EscapeWQLString(instanceName) &amp;"' AND IPAddressName = 'IPAll' AND (PropertyName = 'TcpPort' OR PropertyName = 'TcpDynamicPorts') AND PropertyStrVal &lt;&gt; ''")

If (oQuery.Count &gt; 0) Then
tcp = oQuery.ItemIndex(0).PropertyStrVal

If ((tcp &lt;&gt; "0") And (tcp &lt;&gt; "")) Then
serverName = serverName &amp; "," &amp; tcp
Else tcp = ""
End If
End If
Else
Set oQuery = oWMI.ExecQuery("SELECT * FROM ServerNetworkProtocolProperty WHERE ProtocolName = 'Tcp' AND InstanceName = '"&amp; EscapeWQLString(instanceName) &amp;"' AND IPAddressName &lt;&gt; '' AND PropertyName = 'Enabled' AND PropertyNumVal = 1")
If (oQuery.Count &gt; 0) Then
Dim ipAddressName
ipAddressName = oQuery.ItemIndex(0).IPAddressName
Set oQuery = oWMI.ExecQuery("SELECT * FROM ServerNetworkProtocolProperty WHERE ProtocolName = 'Tcp' AND InstanceName = '"&amp; EscapeWQLString(instanceName) &amp;"' AND IPAddressName = '"&amp; EscapeWQLString(ipAddressName) &amp;"' AND (PropertyName = 'TcpPort' OR PropertyName = 'TcpDynamicPorts') AND PropertyStrVal &lt;&gt; ''")
If (oQuery.Count &gt; 0) Then
tcp = oQuery.ItemIndex(0).PropertyStrVal
End If
Set oQuery = oWMI.ExecQuery("SELECT * FROM ServerNetworkProtocolProperty WHERE ProtocolName = 'Tcp' AND InstanceName = '"&amp; EscapeWQLString(instanceName) &amp;"' AND IPAddressName = '"&amp; EscapeWQLString(ipAddressName) &amp;"' AND PropertyName = 'IpAddress' AND PropertyStrVal &lt;&gt; ''")
If (oQuery.Count &gt; 0) Then
ip = oQuery.ItemIndex(0).PropertyStrVal
End If
If ip &lt;&gt; "" Then
serverName = ip
End If
If ((tcp &lt;&gt; "0") And (tcp &lt;&gt; "")) Then
serverName = servername &amp; "," &amp; tcp
Else tcp = ""
End If
End If
End If
End If
On Error Goto 0
BuildServerName = serverName
End Function'#Include File:SQLDatabaseDiscovery.vbs

'Copyright (c) Microsoft Corporation. All rights reserved.
' Parameters that should be passed to this script
' Parameters that should be passed to this script
' 0 MPElement ID ($MPElement$)
' 1 Target Id for ME this rule is running against ($Target/Id$)
' 2 Computer ID
' 3 Computer FQDN
' 4 SQL Connection String for the instance that the DBs are being discovered on
' 5 SQL Instance that this rule is being run for
' 6 Exlcuded database list (prefixed with Exclude:)

Const SQL_DISCOVERY_CONNECT_FAILURE = -1
Const SQL_DISCOVERY_QUERY_FAILURE = -2
Const SQL_DISCOVERY_SUCCESS = 0
Const ERR_CANNOT_INSERT_NULL = 515
Const EVENT_TYPE_ERROR = 1


Dim MAX_INT_VALUE
MAX_INT_VALUE = (2^31)-1

Dim oArgs
Set oArgs = WScript.Arguments
if oArgs.Count &lt;&gt; 8 Then
Wscript.Quit -1
End If

Dim SourceID, ManagedEntityId, TargetComputer, InstanceName, ConnectionString, TargetComputerID, ExcludeList, TcpPort

SourceId = oArgs(0)
ManagedEntityId = oArgs(1)
TargetComputerID = oArgs(2)
TargetComputer = oArgs(3)
ConnectionString = oArgs(4)
InstanceName = oArgs(5)
ExcludeList = Mid(oArgs(6), 9)
TcpPort = oArgs(7)


Dim oAPI, oSQLDiscoveryData

Set oAPI = MOMCreateObject("MOM.ScriptAPI")
set oSQLDiscoveryData = oAPI.CreateDiscoveryData(0, SourceId, ManagedEntityId)

If DoDatabaseDiscovery(InstanceName, ConnectionString, oSQLDiscoveryData, TcpPort) &gt;= 0 Then
StoreExcludeDatabaseListToRegistry InstanceName, ExcludeList
oAPI.LogScriptEvent "DatabaseDiscovery:" &amp; InstanceName, 4201, 4, "Database for SQL instance '" + InstanceName + "' discovers successfully."
Else
oSQLDiscoveryData.IsSnapshot = False
End If
Call oAPI.Return(oSQLDiscoveryData)
WScript.Quit()

' This function should be used to escape Database Name parameter
Function EscapeDBName (ByVal strValue)
ON ERROR RESUME NEXT
Err.Clear
EscapeDBName = Replace(strValue, "]", "]]")
End Function

Sub WriteToEventLogAndExit(ByVal message)
oAPI.LogScriptEvent WScript.ScriptName, 4201, EVENT_TYPE_ERROR, message

WScript.Quit()
End Sub

Function DoDatabaseDiscovery(ByVal sSqlInstance, ByVal sSQLConnectionString, ByVal oDisc, ByVal tcp)

If Len(ExcludeList) &lt; 0 Then
WriteToEventLogAndExit("Database exclusion list invalid in DBDiscovery. Aborting discovery.")
End If

Dim e
Set e = New Error

Dim cnADOConnection
Set cnADOConnection = MomCreateObject("ADODB.Connection")
cnADOConnection.Provider = "sqloledb"
cnADOConnection.ConnectionTimeout = 30

Dim cnADOConnectionGroup
Set cnADOConnectionGroup = MomCreateObject("ADODB.Connection")
cnADOConnectionGroup.Provider = "sqloledb"
cnADOConnectionGroup.ConnectionTimeout = 30

Dim strProv
strProv = BuildConnectionStringWithPort(sSQLConnectionString, "master", tcp)


e.Clear
On Error Resume Next
cnADOConnection.Open strProv
e.Save
'get fresh tcp port and try to connect again
if 0 &lt;&gt; Err.number then
e.Clear
Err.Clear
strProv = BuildConnectionString(sSQLConnectionString, "master")
cnADOConnection.Open strProv
e.Save

if 0 &lt;&gt; Err.number then
'Error event in here
DoDatabaseDiscovery = SQL_DISCOVERY_CONNECT_FAILURE
Exit Function
end if
end if
On Error Goto 0

Dim oResults, gResults,pResult
e.Clear
On Error Resume Next
Set oResults = cnADOConnection.Execute("SELECT name, state_desc, resource_pool_id as resource_pool_id FROM sys.databases WHERE source_database_id IS NULL")
e.Save
On Error Goto 0
If e.Number &lt;&gt; 0 Then
DoDatabaseDiscovery = SQL_DISCOVERY_QUERY_FAILURE
Exit Function
End If

On Error Resume Next
Set pResult = cnADOConnection.Execute("select Count(pool_id) from sys.dm_resource_governor_resource_pools")
e.Save
On Error Goto 0
If e.Number &lt;&gt; 0 Then
DoDatabaseDiscovery = SQL_DISCOVERY_QUERY_FAILURE
Exit Function
End If

Dim iDBRow, iRow, sFileType
Dim iPos, iPos2, iTemp, bDBAuto, bLogAuto
Dim oDBResults, oDBInstance, sDBSize, sDBStatus
Dim sDBName, sDBState
Dim dDBSize, dLogSize
Dim sDBOwner
Dim oPool, oPoolRel, sPool, sPoolName
Dim NumberOfPool
NumberOfPool = pResult(0).Value

Do While Not oResults.EOF
sDBName = oResults(0)
sDBState = oResults(1)
sPool = oResults(2)
'sPoolName = oResults(3)

If Not(IsExcluded(SDBName)) Then
Set oDBInstance = oSQLDiscoveryData.CreateClassInstance(SQL_DATABASE_CLASS)
' Set basic DB properties
With oDBInstance
.AddProperty "$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", TargetComputerID
.AddProperty "$MPElement[Name='Microsoft.SQLServer.2014.ServerRole']/InstanceName$", sSqlInstance
.AddProperty "$MPElement[Name='Microsoft.SQLServer.2014.Database']/DatabaseName$", sDBName
End With

' Only do further discovery for DB that is online - sp_helpdb wont return state for offline databases
' To do - may want to add owner, created, dbid and compat level to discovery, collation etc.

If sDBState = "ONLINE" Then
On Error Resume Next
Set oDBResults = cnADOConnection.Execute("sp_helpdb [" &amp; EscapeDBName(sDBName) &amp; "]")
e.Save
On Error Goto 0
Select Case e.Number

Case 0
On Error Resume Next
sDBSize = Trim(oDBResults(1))
e.Save
On Error Goto 0
If e.Number = 0 Then
sDBSize = Trim(oDBResults(1))
sDBStatus = Split(oDBResults(5),",")
sDBOwner = oDBResults(2)

Set oDBResults = oDBResults.NextRecordset
bDBAuto = false
bLogAuto = false

dDBSize = 0
dLogSize = 0

Do While Not oDBResults.EOF
sFileType = oDBResults(7)

If LCase(sFileType) = "data only" Then
If (Trim(oDBResults(6)) &lt;&gt; "0%") And (Trim(oDBResults(6)) &lt;&gt; "0 KB") Then
bDBAuto = true
End If
End If
If LCase(sFileType) = "log only" Then
If (Trim(oDBResults(6)) &lt;&gt; "0%") And (Trim(oDBResults(6)) &lt;&gt; "0 KB") Then
bLogAuto = true
End If
End If
oDBResults.MoveNext
Loop

With oDBInstance
.AddProperty "$MPElement[Name='Microsoft.SQLServer.2014.Database']/RecoveryModel$", Split(sDBStatus(3),"=")(1)
.AddProperty "$MPElement[Name='Microsoft.SQLServer.2014.Database']/Updateability$", Split(sDBStatus(1),"=")(1)
.AddProperty "$MPElement[Name='Microsoft.SQLServer.2014.Database']/UserAccess$", Split(sDBStatus(2),"=")(1)
.AddProperty "$MPElement[Name='Microsoft.SQLServer.2014.Database']/Collation$", Split(sDBStatus(5),"=")(1)
.AddProperty "$MPElement[Name='Microsoft.SQLServer.2014.Database']/DatabaseAutogrow$", CStr(bDBAuto)
.AddProperty "$MPElement[Name='Microsoft.SQLServer.2014.Database']/LogAutogrow$", CStr(bLogAuto)
If Not(IsNull(sDBOwner)) Then
.AddProperty "$MPElement[Name='Microsoft.SQLServer.2014.Database']/Owner$", sDBOwner
End If
End With
End If


Case ERR_CANNOT_INSERT_NULL
' Throw error to event log in here
' Error text will be "The system stored procedure sp_helpdb, which is used to gather information about the databases, has returned an error that may indicate that it cannot determine the db owner for the database [" &amp; strDBName &amp; ']. Here are the details: sp_helpdb @dbName='" &amp; strDBName &amp; "' on SQL Server Instance: " &amp; strSQLServerInstanceName &amp; ". Error number: " &amp; e.Number &amp; ", Error Information: " &amp; e.Description, _


Case Else
' Throw error to event log in here
' Error text will be "Could not execute sp_helpdb @dbname=N'" &amp; Replace(strDBName, "'", "''") &amp; "' on SQL Server Instance: " &amp; strSQLServerInstanceName &amp; ". Error number: " &amp; e.Number &amp; ", Error Information: " &amp; e.Description, _


End Select
Set oDBResults = nothing
End If

'create source
'
'We have to check if there is only one pool. Because Hekaton was implemented in Enterprise Edition.
'Enterprise Edition has two build-in resource pools they are internal and default and customer can add his own pools.
'
sPoolName = ""
If NumberOfPool &gt; 1 Then
Set oPool = Nothing
If IsNull( sPool ) Then
On Error Resume Next
' query for the list of databases which are not database snapshots
strProv = BuildConnectionString(sSQLConnectionString, sDBName)
cnADOConnectionGroup.Open strProv
e.Save
Set gResults = cnADOConnectionGroup.Execute("SELECT name FROM sys.filegroups WHERE type = 'FX'")
e.Save
if Not gResults.EOF Then
Set oPool = oSQLDiscoveryData.CreateClassInstance(SQL_DEFAULTPOOL_CLASS)
Set oPoolRel = oSQLDiscoveryData.CreateRelationshipInstance(SQL_DATABASE_REFERENCES_APPLICATION_POOL)
sPool = 2
End if
cnADOConnectionGroup.Close
On Error Goto 0
Else
Set oPool = oSQLDiscoveryData.CreateClassInstance(SQL_DEDICATED_CLASS)
Set oPoolRel = oSQLDiscoveryData.CreateRelationshipInstance(SQL_DATABASE_REFERENCES_APPLICATION_POOL)
End If

'if there is no FX group when sPool will be null
If Not IsNull( sPool ) Then

'let's get a pool name.
Dim poolResult
On Error Resume Next
Set poolResult = cnADOConnection.Execute("select name,pool_id from sys.dm_resource_governor_resource_pools where pool_id = " &amp; sPool)
e.Save
On Error Goto 0
if Not poolResult.EOF Then
sPoolName = poolResult(0).Value
With oPool
.AddProperty "$MPElement[Name='Microsoft.SQLServer.2014.ResourcePool']/PoolID$", sPool
.AddProperty "$MPElement[Name='Microsoft.SQLServer.2014.ResourcePool']/Name$", sPoolName
.AddProperty "$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", TargetComputerID
.AddProperty "$MPElement[Name='Microsoft.SQLServer.2014.ServerRole']/InstanceName$", sSqlInstance
.AddProperty "$MPElement[Name='System!System.Entity']/DisplayName$", sPoolName
End With
'create relationship
oPoolRel.Source = oDBInstance
oPoolRel.Target = oPool
Call oSQLDiscoveryData.AddInstance(oPoolRel)
End if
End If
End If

oDBInstance.AddProperty "$MPElement[Name='Microsoft.SQLServer.2014.Database']/ResourcePool$", sPoolName

' Add DB to the Instance List and move to next DB
call oSQLDiscoveryData.AddInstance(oDBInstance)

End If
oResults.MoveNext

Loop

Set oResults = nothing
cnADOConnection.Close
DoDatabaseDiscovery = SQL_DISCOVERY_SUCCESS

End Function


Function ConvertSizeStringToNumber(sSizeString)
' Remove the KB and return a valid double
sSizeString = Replace(sSizeString, " KB", "")
ConvertSizeStringToNumber = CDbl(sSizeString)
End Function

Function IsExcluded (sDatabase)

Dim aExcludes
Dim match
Dim i

match = false
If Trim(ExcludeList) = "*" Then
match = true
Else
aExcludes = Split(ExcludeList, ",")
For i = 0 To UBound(aExcludes)
If LCase(sDatabase) = LCase(Trim(aExcludes(i))) Then
match = true
End If
Next
End If
IsExcluded = match

End Function


Function StoreExcludeDatabaseListToRegistry(instanceName, ExcludeList)
Dim regKey
Dim oError
Set oError = New Error

On Error Resume Next
regKey = oAPI.GetScriptStateKeyPath("$Target/ManagementGroup/Id$")
regKey = "HKEY_LOCAL_MACHINE\" + regKey + "\" + instanceName + "\DatabaseExcludeList"
oError.Save
On Error Goto 0
If oError.Number &lt;&gt; 0 Then ThrowScriptError "Unable to get database exclude list registry key", oError

Dim wShell
Set wShell = MOMCreateObject("WScript.Shell")

On Error Resume Next
wShell.RegWrite regKey, ExcludeList
oError.Save
On Error Goto 0

If oError.Number &lt;&gt; 0 Then ThrowScriptError "Unable to save database exclude list to registry ", oError
End Function

</Script></ScriptBody>
<TimeoutSeconds>$Config/TimeoutSeconds$</TimeoutSeconds>
</DataSource>
</MemberModules>
<Composition>
<Node ID="DS"/>
</Composition>
</Composite>
</ModuleImplementation>
<OutputType>System!System.Discovery.Data</OutputType>
</DataSourceModuleType>