This object discovery detects any Microsoft Analytics Platform System Nodes and Component Groups.
This object discovery detects all Nodes and Component Groups of particular Microsoft Analytics Platform System.
Target | Microsoft.SQLServerAppliance.APS.Appliance |
Enabled | True |
Frequency | 14400 |
Remotable | False |
ID | Module Type | TypeId | RunAs |
---|---|---|---|
DS | DataSource | Microsoft.SQLServerAppliance.APS.ScriptedDiscoveryProvider | Default |
<Discovery ID="Microsoft.SQLServerAppliance.APS.ApplianceNodes.Discovery" Target="APSLibrary!Microsoft.SQLServerAppliance.APS.Appliance" Enabled="true">
<Category>Discovery</Category>
<DiscoveryTypes>
<DiscoveryClass TypeID="APSLibrary!Microsoft.SQLServerAppliance.APS.Appliance">
<Property TypeID="SSALibrary!Microsoft.SQLServerAppliance.Appliance" PropertyID="ApplianceVersion"/>
<Property TypeID="SSALibrary!Microsoft.SQLServerAppliance.Appliance" PropertyID="ApplianceManufacturer"/>
</DiscoveryClass>
<DiscoveryClass TypeID="APSLibrary!Microsoft.SQLServerAppliance.APS.HostNodesCluster">
<Property TypeID="APSLibrary!Microsoft.SQLServerAppliance.APS.NodesCluster" PropertyID="ApplianceID"/>
<Property TypeID="APSLibrary!Microsoft.SQLServerAppliance.APS.NodesCluster" PropertyID="Name"/>
<Property TypeID="APSLibrary!Microsoft.SQLServerAppliance.APS.NodesCluster" PropertyID="ApplianceNetworkAddress"/>
<Property TypeID="APSLibrary!Microsoft.SQLServerAppliance.APS.NodesCluster" PropertyID="ApplianceTdsAddress"/>
</DiscoveryClass>
<DiscoveryClass TypeID="APSLibrary!Microsoft.SQLServerAppliance.APS.HostNode"/>
<DiscoveryClass TypeID="APSLibrary!Microsoft.SQLServerAppliance.APS.ComputeNode"/>
<DiscoveryClass TypeID="APSLibrary!Microsoft.SQLServerAppliance.APS.ControlNode"/>
<DiscoveryClass TypeID="APSLibrary!Microsoft.SQLServerAppliance.APS.ManagementNode"/>
<DiscoveryClass TypeID="APSLibrary!Microsoft.SQLServerAppliance.APS.HDI.HeadNode"/>
<DiscoveryClass TypeID="APSLibrary!Microsoft.SQLServerAppliance.APS.HDI.DataNode"/>
<DiscoveryClass TypeID="APSLibrary!Microsoft.SQLServerAppliance.APS.HDI.ManagementNode"/>
<DiscoveryClass TypeID="APSLibrary!Microsoft.SQLServerAppliance.APS.HDI.SecureNode"/>
<DiscoveryClass TypeID="APSLibrary!Microsoft.SQLServerAppliance.APS.Network"/>
<DiscoveryClass TypeID="APSLibrary!Microsoft.SQLServerAppliance.APS.Cluster"/>
<DiscoveryClass TypeID="APSLibrary!Microsoft.SQLServerAppliance.APS.Software"/>
<DiscoveryClass TypeID="APSLibrary!Microsoft.SQLServerAppliance.APS.StorageExternal"/>
<DiscoveryClass TypeID="APSLibrary!Microsoft.SQLServerAppliance.APS.StorageInternal"/>
<DiscoveryClass TypeID="APSLibrary!Microsoft.SQLServerAppliance.APS.Cooling"/>
<DiscoveryClass TypeID="APSLibrary!Microsoft.SQLServerAppliance.APS.PowerSupply"/>
<DiscoveryClass TypeID="APSLibrary!Microsoft.SQLServerAppliance.APS.ServerProcessing"/>
</DiscoveryTypes>
<DataSource ID="DS" TypeID="Microsoft.SQLServerAppliance.APS.ScriptedDiscoveryProvider">
<IntervalSeconds>14400</IntervalSeconds>
<SyncTime/>
<ScriptName>APSApplianceNodesDiscovery.vbs</ScriptName>
<Arguments>"$MPElement$" "$Target/Id$" "$Target/Host/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/PrincipalName$" "$Target/Property[Type="SSALibrary!Microsoft.SQLServerAppliance.Appliance"]/ApplianceID$" "$Target/Property[Type="APSLibrary!Microsoft.SQLServerAppliance.APS.Appliance"]/NetworkAddress$" "$Target/Property[Type="APSLibrary!Microsoft.SQLServerAppliance.APS.Appliance"]/TdsAddress$"</Arguments>
<ScriptBody> Option Explicit
SetLocale("en-us")
' Eventlog EventID for all errors generated by scripts
Const SCRIPT_EVENT_ID = 4320
' This string will be appended to the beginning of first Event description parameter (Params/Param[1])
' Use <RegExExpression /> to narrow alerts to this MP only
Const MANAGEMENT_PACK_ID = "SQL2012APS MP"
Dim USE_EVENT_LOG, USE_ERROR_LOG
Const DEBUG_MODE = False
Const DEBUG_SCRIPT_EVENT_ID = 4201
USE_EVENT_LOG = true
USE_ERROR_LOG = false
Const ManagementGroupName = "$Target/ManagementGroup/Name$"
Dim sApplianceID
sApplianceID = ""
Sub LogWarning(ByVal customMessage)
Dim logger
Set logger = new ScriptLogger
logger.LogWarning(customMessage)
End Sub
Sub HandleWarning(ByVal customMessage)
Dim logger
If Err.number <> 0 Then
Set logger = new ScriptLogger
logger.LogWarning(customMessage)
End If
End Sub
Sub HandleError(ByVal customMessage)
Dim logger
If Err.number <> 0 Then
Set logger = new ScriptLogger
logger.LogError(customMessage)
If Not USE_ERROR_LOG Then
Wscript.Quit 0
Else
Wscript.Quit 1
End If
End If
End Sub
Sub HandleErrorInMonitoring(ByVal customMessage, ByRef oBag, ByRef oAPI)
Dim logger
If Err.number <> 0 Then
Set logger = new ScriptLogger
logger.LogError(customMessage)
Call oAPI.Return(oBag)
Wscript.Quit 0
End If
End Sub
Sub HandleErrorInDiscovery(ByVal customMessage, ByRef oDiscovery, ByRef oAPI)
Dim logger
If Err.number <> 0 Then
Set logger = new ScriptLogger
logger.LogError(customMessage)
oDiscovery.IsSnapshot = false
HandleDebugMessage("Discovery: IsSnapshot = false")
oAPI.Return(oDiscoveryData)
Wscript.Quit 0
End If
End Sub
Sub HandleNonCriticalErrorInDiscovery(ByVal customMessage, ByRef oDiscovery)
Dim logger
Set logger = new ScriptLogger
logger.LogError(customMessage)
oDiscovery.IsSnapshot = false
HandleDebugMessage("Discovery: IsSnapshot = false")
End Sub
Sub HandleDebugMessage(ByVal debugMessage)
Dim logger
Set logger = new ScriptLogger
logger.LogDebug(debugMessage)
End Sub
Const ERROR_EVENT_TYPE = 1
Const WARNING_EVENT_TYPE = 2
Const INFO_EVENT_TYPE = 4
Class ScriptLogger
Dim sourceLogEvent
Dim oAPI
Private Sub Class_Initialize()
sourceLogEvent = MANAGEMENT_PACK_ID
If (sApplianceID <> "") Then
sourceLogEvent = sourceLogEvent & ". Appliance: " & sApplianceID
End If
sourceLogEvent = sourceLogEvent & ". Script: " & WScript.ScriptName
Set oAPI = CreateObject("MOM.ScriptAPI")
End Sub
Private Function LogEvent(ByVal message, ByVal eventType, ByVal scriptEventID)
On Error Resume Next
Call oAPI.LogScriptEvent(sourceLogEvent, scriptEventID, eventType, message)
End Function
Public Function LogDebug(ByVal message)
if DEBUG_MODE Then
WScript.StdOut.WriteLine message
Call oAPI.LogScriptEvent(sourceLogEvent, DEBUG_SCRIPT_EVENT_ID, INFO_EVENT_TYPE, message)
End If
End Function
Public Function LogWarning(ByVal customMessage)
Dim message
If Err.number <> 0 Then
message = Replace(" Error Number: #P1# " & VbCrLf & " Description: #P2# ", "#P1#", CStr(Err.number and 65535) )
message = Replace(message, "#P2#", Err.Description )
message = customMessage & VbCrLf & message & VbCrLf
Else
message = customMessage & VbCrLf
End If
if DEBUG_MODE Then
WScript.StdOut.WriteLine message
End If
LogEvent message, WARNING_EVENT_TYPE, SCRIPT_EVENT_ID
End Function
Public Function LogError(ByVal customMessage)
Dim message
If Err.number <> 0 Then
message = Replace(" Error Number: #P1# " & VbCrLf & " Description: #P2# ", "#P1#", CStr(Err.number and 65535) )
message = Replace(message, "#P2#", Err.Description )
message = customMessage & VbCrLf & message & VbCrLf
Else
message = customMessage & VbCrLf
End If
If DEBUG_MODE Then
WScript.StdOut.WriteLine message
End If
If USE_EVENT_LOG Then
LogEvent message, ERROR_EVENT_TYPE, SCRIPT_EVENT_ID
End If
If USE_ERROR_LOG Then
WScript.StdErr.WriteLine message
End If
End Function
End Class
Function IsStringEmpty(ByVal sValue)
If sValue = EMPTY Or Trim(sValue) = "" Then
IsStringEmpty = true
Else
IsStringEmpty = false
End If
End Function
Const DEFAULT_SCHEMA = "[sys]"
'This class is wrapper for ADODB typical operations (Connect and Run SQL query)
Class SQLQuery
PRIVATE adodbConnection
Private Sub Class_Initialize()
On Error Resume Next
Set adodbConnection = CreateObject("ADODB.Connection")
Call HandleError("Cannot create ADODB.Connection")
End Sub
Private Sub Class_Terminate()
On Error Resume Next
'adodbConnection.State = 0 - Closed
If adodbConnection.State > 0 Then
Call adodbConnection.Close()
End If
Call HandleError("Cannot close ADODB.Connection")
End Sub
'This method create and open connection to the server
'<connectionString> - host address to be used for connection;
Public Sub Connect(ByVal connectionString, ByVal sUser, ByVal sPass, ByVal nTimeout)
On Error Resume Next
Dim providerString, bSuccess, sDriver
bSuccess = False
Dim aSupportedDrivers : aSupportedDrivers = Array("10.0","11.0")
adodbConnection.ConnectionTimeout = nTimeout
' Since PDW allows for either SNAC 10 or 11 versions, the connection logic
' should retry for both if one failed to connect.
For Each sDriver In aSupportedDrivers
Call Err.Clear
providerString = "Driver={SQL Server Native Client " & sDriver & "};Server=" & connectionString & ";UID=" & sUser & ";PWD=" & sPass
Call adodbConnection.Open(providerString)
If adodbConnection.State <> 1 Then
' Retry if connection failed with next version number
Else
bSuccess = True
Exit For
End If
Next
End Sub
'This function execute <query> with <parameters> and returns ADODB.RecordSet
'<parameters> must be array, and must be with the same order as sql query <?> paremetrs
Public Function ExecuteQueryToRecordSet(ByVal query, ByVal parameters)
Dim adodbCommand, oResults
Set adodbCommand = CreateObject("ADODB.Command")
adodbCommand.ActiveConnection = adodbConnection
adodbCommand.CommandText = query
Dim i, dataType, dataSize, parameter, length
length = UBound(parameters)
'Put parameters in to ADODB.Command
For i=0 To length
parameter = parameters(i)
dataType = GetDataTypeEnum(parameter)
dataSize = GetDataTypeSize(parameter)
adodbCommand.Parameters.Append(adodbCommand.CreateParameter("p"&i, dataType, 1, dataSize, parameter)) '1 - this is adParamInput in ADODB. see http://www.w3schools.com/ado/met_comm_createparameter.asp#parameterdirenum
Next
Set ExecuteQueryToRecordSet = adodbCommand.Execute()
End Function
'returns size of string or 0 for others types
Private Function GetDataTypeSize(ByVal vValue)
If TypeName(vValue)="String" Then
GetDataTypeSize = Len(vValue)
Else
GetDataTypeSize = 0
End If
End Function
'this function returns int value of some DataTypeEnum
'values of adodb types see on http://www.w3schools.com/ado/met_comm_createparameter.asp#datatypeenum
Private Function GetDataTypeEnum(ByVal vValue)
If TypeName(vValue) = "Byte" Then
GetDataTypeEnum = 2 ' adSmallInt=2
End If
If TypeName(vValue)="Integer" or TypeName(vValue)="Long" Then
GetDataTypeEnum = 3 ' adInteger=3
End If
If TypeName(vValue)="Double" Then
GetDataTypeEnum = 5 ' adDouble=5
End If
If TypeName(vValue)="String" Then
GetDataTypeEnum = 8 ' adBSTR = 8
End If
End Function
End Class
On Error Resume Next
Dim GetApplianceVendorQuery, GetApplianceVersionQuery, GetNodesQuery, GetComponentGroupsQuery
GetApplianceVendorQuery = Replace("SELECT " & _
" CASE ISNULL(MAX(LEFT(group_id, 1)), 0) " & _
" WHEN 1 THEN 'Microsoft' " & _
" WHEN 2 THEN 'HP' " & _
" WHEN 3 THEN 'DELL' " & _
" WHEN 4 THEN 'SWIFT' " & _
" ELSE 'Unknown' " & _
" END as 'appliance_vendor' " & _
" FROM {0}.[pdw_health_component_groups] " & _
" OPTION (LABEL = 'SCOM-APS-MP');", "{0}", DEFAULT_SCHEMA)
GetApplianceVersionQuery = "SELECT RTRIM(left(version(), charindex(' (X64)', version(), 0))) as 'pdw_version' OPTION (LABEL = 'SCOM-PDW-MP');"
GetNodesQuery = Replace("SELECT n.[pdw_node_id], n.[type], n.[name], n.[address], n.[is_passive], nc.[cluster_name], n.[region] as 'owning_region' " & _
" FROM {0}.[dm_pdw_nodes] n " & _
" LEFT OUTER JOIN ( SELECT DISTINCT s.[pdw_node_id], s.[property_value] as 'cluster_name' " & _
" FROM {0}.[dm_pdw_component_health_status] s " & _
" JOIN {0}.[pdw_health_components] c " & _
" ON s.[component_id] = c.[component_id] " & _
" JOIN {0}.[pdw_health_component_groups] g " & _
" ON c.[group_id] = g.[group_id] " & _
" JOIN {0}.[pdw_health_component_properties] p " & _
" ON s.[property_id] = p.[property_id] " & _
" AND s.[component_id] = p.[component_id] " & _
" WHERE " & _
" g.[group_name] = 'Cluster' " & _
" AND c.[component_name] = 'Node' " & _
" AND p.[property_name] = 'cluster_name' " & _
" ) nc ON nc.[pdw_node_id] = n.[pdw_node_id] " & _
" OPTION (LABEL = 'SCOM-APS-MP');", "{0}", DEFAULT_SCHEMA)
GetComponentGroupsQuery = Replace("SELECT " & _
" nodes.[pdw_node_id] " & _
" , nodes.[name] " & _
" , groups.[group_id] " & _
" , groups.[group_name] " & _
" FROM " & _
" {0}.[dm_pdw_component_health_status] healthStatus " & _
" INNER JOIN {0}.dm_pdw_nodes nodes " & _
" ON healthStatus.pdw_node_id = nodes.pdw_node_id " & _
" INNER JOIN {0}.pdw_health_components components " & _
" ON healthStatus.component_id = components.component_id " & _
" INNER JOIN {0}.pdw_health_component_groups groups " & _
" ON components.group_id = groups.group_id " & _
" GROUP BY " & _
" nodes.[pdw_node_id] " & _
" , nodes.[name] " & _
" , groups.[group_id] " & _
" , groups.[group_name] " & _
" OPTION (LABEL = 'SCOM-APS-MP');", "{0}", DEFAULT_SCHEMA)
Dim oAPI, oDiscoveryData
Dim SourceID, ManagedEntityID, sPrincipalName, sNetworkAddress, sTdsAddress
Dim oAppliance
Dim sUser, sPass
Dim oSqlQry
Set oAPI = CreateObject("MOM.ScriptAPI")
Call HandleError("Cannot create MOM.ScriptAPI object")
Call Main()
Sub Main()
On Error Resume Next
Dim oSecureInput
oSecureInput = Split(WScript.StdIn.ReadLine(), "@@secureseparator@@")
sUser = oSecureInput(0)
Call HandleError("Cannot read Username from SecureInput")
sPass = oSecureInput(1)
Call HandleError("Cannot read Password from SecureInput")
Dim oParams
Set oParams = WScript.Arguments
SourceID = oParams(0)
Call HandleError("Cannot read Source ID from parameters")
ManagedEntityID = oParams(1)
Call HandleError("Cannot read Managed Entity ID from parameters")
sPrincipalName = oParams(2)
Call HandleError("Cannot read Principal Name from parameters")
sApplianceID = oParams(3)
Call HandleError("Cannot read Appliance ID from parameters")
sNetworkAddress = oParams(4)
Call HandleError("Cannot read Network Address from parameters")
sTdsAddress = oParams(5)
Call HandleError("Cannot read TDS Address from parameters")
Set oDiscoveryData = oAPI.CreateDiscoveryData(0, SourceId, ManagedEntityID)
Call HandleError("Cannot create Discovery Data object")
Set oSqlQry = new SQLQuery
Call oSqlQry.Connect(sTdsAddress, sUser, sPass, 60)
Call HandleErrorInDiscovery("Connection failed", oDiscoveryData, oAPI)
Set oAppliance = oDiscoveryData.CreateClassInstance("$MPElement[Name='APSLibrary!Microsoft.SQLServerAppliance.APS.Appliance']$")
Call oAppliance.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", sPrincipalName)
Call oAppliance.AddProperty("$MPElement[Name='SSALibrary!Microsoft.SQLServerAppliance.Appliance']/ApplianceID$", sApplianceID)
Call oAppliance.AddProperty("$MPElement[Name='SSALibrary!Microsoft.SQLServerAppliance.Appliance']/ApplianceVersion$", GetApplianceVersion())
Call oAppliance.AddProperty("$MPElement[Name='SSALibrary!Microsoft.SQLServerAppliance.Appliance']/ApplianceManufacturer$", GetApplianceVendor())
Call oDiscoveryData.AddInstance(oAppliance)
Dim hNodes
Set hNodes = CreateObject("Scripting.Dictionary")
Call HandleError("Cannot create Scripting.Dictionary object")
Call DiscoverNodes(hNodes)
Call DiscoverComponentGroups(hNodes)
Call oAPI.Return(oDiscoveryData)
End Sub
Function GetApplianceVendor
On Error Resume Next
Dim oRecordSet
Set oRecordSet = oSqlQry.ExecuteQueryToRecordSet(GetApplianceVendorQuery, Array())
Call HandleWarning("Cannot determine Appliance Vendor")
GetApplianceVendor = oRecordSet(0)
oRecordSet.Close()
End Function
Function GetApplianceVersion
On Error Resume Next
Dim oRecordSet
Set oRecordSet = oSqlQry.ExecuteQueryToRecordSet(GetApplianceVersionQuery, Array())
Call HandleWarning("Cannot determine Appliance Version")
GetApplianceVersion = oRecordSet(0)
oRecordSet.Close()
End Function
Sub DiscoverNodes(ByRef hNodes)
On Error Resume Next
Dim hHostNodesClusters, oCluster
Set hHostNodesClusters = CreateObject("Scripting.Dictionary")
Call HandleError("Cannot create Scripting.Dictionary object")
Dim oRecordSet
Set oRecordSet = oSqlQry.ExecuteQueryToRecordSet(GetNodesQuery, Array())
Call HandleErrorInDiscovery("Cannot run query", oDiscoveryData, oAPI)
Dim oNode, nNodeID, sNodeType, sNodeTypeLowered, sClusterName, sName, sAddress, bIsPassive, sOwningRegion, sRegion
Dim oHostNodesClustersGroup, oRelationship
Dim bIsClustersGroupDiscovered : bIsClustersGroupDiscovered = False
Set oHostNodesClustersGroup = oDiscoveryData.CreateClassInstance("$MPElement[Name='APSLibrary!Microsoft.SQLServerAppliance.APS.HostNodesClustersGroup']$")
Call oHostNodesClustersGroup.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", sPrincipalName)
Call oHostNodesClustersGroup.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", "Host Nodes Clusters")
Call oHostNodesClustersGroup.AddProperty("$MPElement[Name='APSLibrary!Microsoft.SQLServerAppliance.APS.HostNodesClustersGroup']/ApplianceID$", sApplianceID)
Do While Not oRecordSet.EOF
nNodeID = oRecordSet(0)
sNodeType = oRecordSet(1)
sNodeTypeLowered = LCase(sNodeType)
sName = oRecordSet(2)
sAddress = oRecordSet(3)
bIsPassive = oRecordSet(4)
sClusterName = oRecordSet(5)
sOwningRegion = oRecordSet(6)
oCluster = Empty
Call CreateNode(sNodeTypeLowered, oNode, sRegion)
If (Not IsEmpty(oNode)) Then
Call FillNodeProperties(oNode, nNodeID, sNodeType, sName, sAddress, sClusterName, bIsPassive, sRegion, sOwningRegion)
Call oDiscoveryData.AddInstance(oNode)
Call hNodes.Add(nNodeID, oNode)
' Nodes to Cluster
If (Not IsNull(sClusterName)) Then
If sNodeTypeLowered = "host" Then
If (Not bIsClustersGroupDiscovered) Then
Call oDiscoveryData.AddInstance(oHostNodesClustersGroup)
Call AddContainmentRelationship("$MPElement[Name='APSLibrary!Microsoft.SQLServerAppliance.APS.ApplianceContainsHostNodesClustersGroup']$", oAppliance, oHostNodesClustersGroup)
bIsClustersGroupDiscovered = True
End If
Dim bIsNewClusterCreated
bIsNewClusterCreated = EnsureCluster(hHostNodesClusters, "$MPElement[Name='APSLibrary!Microsoft.SQLServerAppliance.APS.HostNodesCluster']$", sClusterName)
Set oCluster = hHostNodesClusters.Item(sClusterName)
If (bIsNewClusterCreated) Then
Call AddContainmentRelationship("$MPElement[Name='APSLibrary!Microsoft.SQLServerAppliance.APS.HostNodesClustersGroupContainsHostNodesCluster']$", oHostNodesClustersGroup, oCluster)
End If
Call AddContainmentRelationship("$MPElement[Name='APSLibrary!Microsoft.SQLServerAppliance.APS.HostNodesClusterContainsHostNode']$", oCluster, oNode)
End If
Else
' Nodes to Appliance
If sNodeTypeLowered = "management" Then
Call AddContainmentRelationship("$MPElement[Name='APSLibrary!Microsoft.SQLServerAppliance.APS.ApplianceContainsManagementNode']$", oAppliance, oNode)
ElseIf sNodeTypeLowered = "compute" Then
Call AddContainmentRelationship("$MPElement[Name='APSLibrary!Microsoft.SQLServerAppliance.APS.ApplianceContainsComputeNode']$", oAppliance, oNode)
ElseIf sNodeTypeLowered = "control" Then
Call AddContainmentRelationship("$MPElement[Name='APSLibrary!Microsoft.SQLServerAppliance.APS.ApplianceContainsControlNode']$", oAppliance, oNode)
ElseIf sNodeTypeLowered = "hdihead" Then
Call AddContainmentRelationship("$MPElement[Name='APSLibrary!Microsoft.SQLServerAppliance.APS.HDI.ApplianceContainsHDIHeadNode']$", oAppliance, oNode)
ElseIf sNodeTypeLowered = "hdidata" Then
Call AddContainmentRelationship("$MPElement[Name='APSLibrary!Microsoft.SQLServerAppliance.APS.HDI.ApplianceContainsHDIDataNode']$", oAppliance, oNode)
ElseIf sNodeTypeLowered = "hdimanagement" Then
Call AddContainmentRelationship("$MPElement[Name='APSLibrary!Microsoft.SQLServerAppliance.APS.HDI.ApplianceContainsHDIManagementNode']$", oAppliance, oNode)
ElseIf sNodeTypeLowered = "hdisecure" Then
Call AddContainmentRelationship("$MPElement[Name='APSLibrary!Microsoft.SQLServerAppliance.APS.HDI.ApplianceContainsHDISecureNode']$", oAppliance, oNode)
End If
End If
Else
Call LogWarning("Node with ID " & nNodeID & " has unknown type '" & sNodeType & "' and will not be discovered.")
End If
Call oRecordSet.MoveNext()
Loop
Call oRecordSet.Close()
End Sub
' Creates new Node of specified type
Sub CreateNode(ByVal sNodeTypeLowered, ByRef oNode, ByRef sRegion)
Dim sPdw, sHdi, sFabric
sPdw = "Pdw"
sHdi = "Hdi"
sFabric = "Fabric"
If sNodeTypeLowered = "control" Then
Set oNode = oDiscoveryData.CreateClassInstance("$MPElement[Name='APSLibrary!Microsoft.SQLServerAppliance.APS.ControlNode']$")
sRegion = sPdw
ElseIf sNodeTypeLowered = "compute" Then
Set oNode = oDiscoveryData.CreateClassInstance("$MPElement[Name='APSLibrary!Microsoft.SQLServerAppliance.APS.ComputeNode']$")
sRegion = sPdw
ElseIf sNodeTypeLowered = "management" Then
Set oNode = oDiscoveryData.CreateClassInstance("$MPElement[Name='APSLibrary!Microsoft.SQLServerAppliance.APS.ManagementNode']$")
sRegion = sPdw
ElseIf sNodeTypeLowered = "host" Then
Set oNode = oDiscoveryData.CreateClassInstance("$MPElement[Name='APSLibrary!Microsoft.SQLServerAppliance.APS.HostNode']$")
sRegion = sFabric
ElseIf sNodeTypeLowered = "hdihead" Then
Set oNode = oDiscoveryData.CreateClassInstance("$MPElement[Name='APSLibrary!Microsoft.SQLServerAppliance.APS.HDI.HeadNode']$")
sRegion = sHdi
ElseIf sNodeTypeLowered = "hdidata" Then
Set oNode = oDiscoveryData.CreateClassInstance("$MPElement[Name='APSLibrary!Microsoft.SQLServerAppliance.APS.HDI.DataNode']$")
sRegion = sHdi
ElseIf sNodeTypeLowered = "hdimanagement" Then
Set oNode = oDiscoveryData.CreateClassInstance("$MPElement[Name='APSLibrary!Microsoft.SQLServerAppliance.APS.HDI.ManagementNode']$")
sRegion = sHdi
ElseIf sNodeTypeLowered = "hdisecure" Then
Set oNode = oDiscoveryData.CreateClassInstance("$MPElement[Name='APSLibrary!Microsoft.SQLServerAppliance.APS.HDI.SecureNode']$")
sRegion = sHdi
Else
oNode = Empty
sRegion = Empty
End If
End Sub
' Populates Node's properties
Sub FillNodeProperties(ByRef oNode, ByVal nNodeID, ByVal sNodeType, ByVal sName, ByVal sAddress, ByVal sClusterName, ByVal bIsPassive, ByVal sRegion, ByVal sOwningRegion)
Call oNode.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", ExtractDisplayName(sName))
Call oNode.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", sPrincipalName)
Call oNode.AddProperty("$MPElement[Name='APSLibrary!Microsoft.SQLServerAppliance.APS.Node']/ApplianceID$", sApplianceID)
Call oNode.AddProperty("$MPElement[Name='APSLibrary!Microsoft.SQLServerAppliance.APS.Node']/ID$", nNodeID)
Call oNode.AddProperty("$MPElement[Name='APSLibrary!Microsoft.SQLServerAppliance.APS.Node']/Type$", sNodeType)
Call oNode.AddProperty("$MPElement[Name='APSLibrary!Microsoft.SQLServerAppliance.APS.Node']/NodeName$", sName)
Call oNode.AddProperty("$MPElement[Name='APSLibrary!Microsoft.SQLServerAppliance.APS.Node']/Address$", sAddress)
If (Not IsNull(sClusterName)) Then
Call oNode.AddProperty("$MPElement[Name='APSLibrary!Microsoft.SQLServerAppliance.APS.Node']/ClusterName$", sClusterName)
Call oNode.AddProperty("$MPElement[Name='APSLibrary!Microsoft.SQLServerAppliance.APS.Node']/ClusterDisplayName$", ExtractDisplayName(sClusterName))
End If
Call oNode.AddProperty("$MPElement[Name='APSLibrary!Microsoft.SQLServerAppliance.APS.Node']/IsPassive$", bIsPassive)
Call oNode.AddProperty("$MPElement[Name='APSLibrary!Microsoft.SQLServerAppliance.APS.Node']/ApplianceNetworkAddress$", sNetworkAddress)
Call oNode.AddProperty("$MPElement[Name='APSLibrary!Microsoft.SQLServerAppliance.APS.Node']/ApplianceTdsAddress$", sTdsAddress)
Call oNode.AddProperty("$MPElement[Name='APSLibrary!Microsoft.SQLServerAppliance.APS.Node']/Region$", sRegion)
If (LCase(sNodeType) = "host") Then
Call oNode.AddProperty("$MPElement[Name='APSLibrary!Microsoft.SQLServerAppliance.APS.HostNode']/OwningRegion$", sOwningRegion)
End If
End Sub
' Ensures cluster existance in collection
' Returns True if new instance was created, False otherwise
Function EnsureCluster(ByRef hClusters, ByVal sClusterType, ByVal sClusterName)
If hClusters.Exists(sClusterName) Then
EnsureCluster = False
Exit Function
End If
Dim oCluster
Set oCluster = oDiscoveryData.CreateClassInstance(sClusterType)
Call oCluster.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", ExtractDisplayName(sClusterName))
Call oCluster.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", sPrincipalName)
Call oCluster.AddProperty("$MPElement[Name='APSLibrary!Microsoft.SQLServerAppliance.APS.NodesCluster']/ApplianceID$", sApplianceID)
Call oCluster.AddProperty("$MPElement[Name='APSLibrary!Microsoft.SQLServerAppliance.APS.NodesCluster']/Name$", sClusterName)
Call oCluster.AddProperty("$MPElement[Name='APSLibrary!Microsoft.SQLServerAppliance.APS.NodesCluster']/ApplianceNetworkAddress$", sNetworkAddress)
Call oCluster.AddProperty("$MPElement[Name='APSLibrary!Microsoft.SQLServerAppliance.APS.NodesCluster']/ApplianceTdsAddress$", sTdsAddress)
Call oDiscoveryData.AddInstance(oCluster)
Call hClusters.Add(sClusterName, oCluster)
EnsureCluster = True
End Function
' Adds containment relationship between specified Source and Target objects
Sub AddContainmentRelationship(ByVal sRealtionshipType, ByRef oSource, ByRef oTarget)
Dim oRelationship
Set oRelationship = oDiscoveryData.CreateRelationshipInstance(sRealtionshipType)
oRelationship.Source = oSource
oRelationship.Target = oTarget
Call oDiscoveryData.AddInstance(oRelationship)
End Sub
' Extracts display name from Node or Cluster name
Function ExtractDisplayName(ByVal sFullName)
ExtractDisplayName = Mid(sFullName, InStr(sFullName, "-") + 1)
End Function
Sub DiscoverComponentGroups(hNodes)
On Error Resume Next
Dim oRecordSet
Set oRecordSet = oSqlQry.ExecuteQueryToRecordSet(GetComponentGroupsQuery, Array())
Call HandleErrorInDiscovery("Cannot run query", oDiscoveryData, oAPI)
Dim oComponentGroup
Dim nNodeID, sNodeName, nGroupID, sGroupName
Do While Not oRecordSet.EOF
nNodeID = oRecordSet(0)
sNodeName = ExtractDisplayName(oRecordSet(1))
nGroupID = RemoveVendorID(oRecordSet(2))
sGroupName = oRecordSet(3)
Call CreateComponentGroup(nGroupID, oComponentGroup)
If Not IsEmpty(oComponentGroup) Then
Call FillComponentGroupProperties(oComponentGroup, nNodeID, nGroupID, sGroupName)
Call oDiscoveryData.AddInstance(oComponentGroup)
Call AddContainmentRelationship("$MPElement[Name='APSLibrary!Microsoft.SQLServerAppliance.APS.NodeContainsComponentGroup']$", hNodes.Item(nNodeID), oComponentGroup)
End If
Call oRecordSet.MoveNext()
Loop
Call oRecordSet.Close()
End Sub
Function RemoveVendorID(ByVal nID)
Dim sID
sID = CStr(nID)
RemoveVendorID = CLng(Right(sID, Len(sID) -3))
End Function
' Creates new Component Group
Sub CreateComponentGroup(ByVal nComponentGroupID, ByRef oComponentGroup)
If nComponentGroupID = 80000 Then
Set oComponentGroup = oDiscoveryData.CreateClassInstance("$MPElement[Name='APSLibrary!Microsoft.SQLServerAppliance.APS.Cluster']$")
ElseIf nComponentGroupID = 60000 Then
Set oComponentGroup = oDiscoveryData.CreateClassInstance("$MPElement[Name='APSLibrary!Microsoft.SQLServerAppliance.APS.Network']$")
ElseIf nComponentGroupID = 20000 Then
Set oComponentGroup = oDiscoveryData.CreateClassInstance("$MPElement[Name='APSLibrary!Microsoft.SQLServerAppliance.APS.StorageExternal']$")
ElseIf nComponentGroupID = 10000 Then
Set oComponentGroup = oDiscoveryData.CreateClassInstance("$MPElement[Name='APSLibrary!Microsoft.SQLServerAppliance.APS.StorageInternal']$")
ElseIf nComponentGroupID = 100000 Then
Set oComponentGroup = oDiscoveryData.CreateClassInstance("$MPElement[Name='APSLibrary!Microsoft.SQLServerAppliance.APS.Software']$")
ElseIf nComponentGroupID = 50000 Then
Set oComponentGroup = oDiscoveryData.CreateClassInstance("$MPElement[Name='APSLibrary!Microsoft.SQLServerAppliance.APS.Cooling']$")
ElseIf nComponentGroupID = 40000 Then
Set oComponentGroup = oDiscoveryData.CreateClassInstance("$MPElement[Name='APSLibrary!Microsoft.SQLServerAppliance.APS.PowerSupply']$")
ElseIf nComponentGroupID = 30000 Then
Set oComponentGroup = oDiscoveryData.CreateClassInstance("$MPElement[Name='APSLibrary!Microsoft.SQLServerAppliance.APS.ServerProcessing']$")
ElseIf nComponentGroupID = 200000 Then
Set oComponentGroup = oDiscoveryData.CreateClassInstance("$MPElement[Name='APSLibrary!Microsoft.SQLServerAppliance.APS.HDI.HDInsight']$")
Else
oComponentGroup = Empty
End If
End Sub
' Populates ComponentGroup's properties
Sub FillComponentGroupProperties(ByRef oComponentGroup, ByVal nNodeID, ByVal nGroupID, ByVal sGroupName)
Call oComponentGroup.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", sGroupName)
Call oComponentGroup.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", sPrincipalName)
Call oComponentGroup.AddProperty("$MPElement[Name='APSLibrary!Microsoft.SQLServerAppliance.APS.ComponentGroup']/ApplianceID$", sApplianceID)
Call oComponentGroup.AddProperty("$MPElement[Name='APSLibrary!Microsoft.SQLServerAppliance.APS.ComponentGroup']/NodeID$", nNodeID)
Call oComponentGroup.AddProperty("$MPElement[Name='APSLibrary!Microsoft.SQLServerAppliance.APS.ComponentGroup']/ID$", nGroupID)
End Sub
</ScriptBody>
<SecureInput>$RunAs[Name="APSLibrary!Microsoft.SQLServerAppliance.APS.ActionProfile"]/UserName$@@secureseparator@@$RunAs[Name="APSLibrary!Microsoft.SQLServerAppliance.APS.ActionProfile"]/Password$</SecureInput>
<TimeoutSeconds>300</TimeoutSeconds>
</DataSource>
</Discovery>