SQL 2012 DB Size Provider

Microsoft.SQLServer.2012.DBSizeRawPerfProvider (DataSourceModuleType)

Element properties:

TypeDataSourceModuleType
IsolationAny
AccessibilityPublic
RunAsMicrosoft.SQLServer.SQLProbeAccount
OutputTypeSystem.Performance.Data

Member Modules:

ID Module Type TypeId RunAs 
DS DataSource Microsoft.Windows.TimedScript.PropertyBagProvider Default
InstanceFilter ConditionDetection System.ExpressionFilter Default
PerfMapper ConditionDetection System.Performance.DataGenericMapper Default

Overrideable Parameters:

IDParameterTypeSelectorDisplay NameDescription
IntervalSecondsint$Config/IntervalSeconds$Interval (sec)
SyncTimestring$Config/SyncTime$Synchronization Time
TimeoutSecondsint$Config/TimeoutSeconds$Timeout (sec)

Source Code:

<DataSourceModuleType ID="Microsoft.SQLServer.2012.DBSizeRawPerfProvider" Accessibility="Public" RunAs="SQL!Microsoft.SQLServer.SQLProbeAccount">
<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="ConnectionString" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="ServerName" 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="ObjectName" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="CounterName" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="InstanceName" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="DatabaseName" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="Value" 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="TimeoutSeconds" ParameterType="int" Selector="$Config/TimeoutSeconds$"/>
</OverrideableParameters>
<ModuleImplementation>
<Composite>
<MemberModules>
<DataSource ID="DS" TypeID="Windows!Microsoft.Windows.TimedScript.PropertyBagProvider">
<IntervalSeconds>$Config/IntervalSeconds$</IntervalSeconds>
<SyncTime>$Config/SyncTime$</SyncTime>
<ScriptName>GetSQL2012DBFreeSpace.vbs</ScriptName>
<Arguments>"$Config/ConnectionString$" "$Config/ServerName$" "$Config/SqlInstanceName$" "$Target/Host/Property[Type="SQL!Microsoft.SQLServer.DBEngine"]/TcpPort$"</Arguments>
<ScriptBody><Script>'#Include File:Common.vbs

Option Explicit
On Error Resume Next

SetLocale("en-us")
HandleErrorContinue("Cannot set en-us locale")

Const DEBUG_MODE = false
Const ManagementGroupName = "$Target/ManagementGroup/Name$"
Const ManagementGroupID = "$Target/ManagementGroup/Id$"
Const SQL_DEFAULT = "MSSQLSERVER"

Dim WShell, FSO, Logger
CreateGlobalObjects()
Main()

''''''''''''''''''''''''''
''' Global Functions
''''''''''''''''''''''''''
Sub CreateGlobalObjects()

Set WShell = CreateObject("wscript.shell")
HandleError("Cannot create object 'wscript.shell' (CreateGlobalObjects).")
Set FSO = CreateObject("Scripting.FileSystemObject")
HandleError("Cannot create object 'Scripting.FileSystemObject'(CreateGlobalObjects).")

Set Logger = new ScriptLogger
HandleError("Cannot create object 'ScriptLogger'(CreateGlobalObjects).")
End Sub

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

Sub ScriptExit()
Wscript.Quit 0
End Sub

Public Function GetSQLServiceName(sInstance)
If sInstance = SQL_DEFAULT Then
GetSQLServiceName = SQL_DEFAULT
Else
GetSQLServiceName = "MSSQL$" &amp; sInstance
End If
End Function

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

EscapeWQLString = Replace(strValue, "'", "\'")
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\" &amp; SQL_WMI_NAMESPACE)
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:Common-SecondPart.vbs

''''''''''''''''''''''''''''''''''''
''' Error
''''''''''''''''''''''''''''''''''''
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

''''''''''''''''''''''''''''''''''''
''' ScriptLogger
''''''''''''''''''''''''''''''''''''
Class ScriptLogger
Dim sourceLogEvent

Private Sub Class_Initialize()
sourceLogEvent = "Management Group: " + ManagementGroupName + ". Script: " + WScript.ScriptName
End Sub

Private Sub Class_Terminate()
End Sub

Public Property Get ErrorEventType
ErrorEventType = 1
End Property

Public Property Get WarningEventType
WarningEventType = 2
End Property

Public Property Get InfoEventType
InfoEventType = 4
End Property

Private Function LogEvent (message, eventType)
On Error Resume Next
Dim oAPI
Set oAPI = CreateObject("MOM.ScriptAPI")
Call oAPI.LogScriptEvent(sourceLogEvent, SCRIPT_EVENT_ID, eventType, message)
End Function

Public Function LogDebug(message)
if DEBUG_MODE Then
WScript.StdOut.WriteLine message
LogEvent message, Me.InfoEventType
End If
End Function

Public Function LogError(message)
if DEBUG_MODE Then
WScript.StdOut.WriteLine message
End If
LogEvent message, Me.ErrorEventType
End Function

Public Function LogWarning(message)
if DEBUG_MODE Then
WScript.StdOut.WriteLine message
End If
LogEvent message, Me.WarningEventType
End Function

Public Function LogFormattedError(customMessage)
Dim msg
If Not (Err.number = 0) Then
msg = Replace(" Error Number: #P1# " &amp; VbCrLf &amp; " Description: #P2# ", "#P1#", CStr(Err.number) )
msg = Replace(msg, "#P2#", Err.Description )
msg = customMessage &amp; VbCrLf &amp; msg &amp; VbCrLf
'msg = msg &amp; " [" &amp; Me.ScriptInfo() &amp; "]"
Me.LogError(msg)
End If
End Function

Private Function ScriptInfo()
Dim commandLineInfo : commandLineInfo = WScript.ScriptFullName
Dim argument
For Each argument In WScript.Arguments
commandLineInfo = commandLineInfo &amp; " """ &amp; argument &amp; """"
Next
ScriptInfo = commandLineInfo
End Function
End Class


''''''''''''''''''''''''''''''''''''
''' Class OpsMgrAPI
''''''''''''''''''''''''''''''''''''
Class OpsMgrAPI
Dim scriptAPI

Private Sub Class_Initialize()
On Error Resume Next
Set scriptAPI = CreateObject("MOM.ScriptAPI")
HandleError("Cannot create object 'MOM.ScriptAPI' (OpsMgrAPI.Class_Initialize).")
End Sub

End Class
'#Include File:SQLADODB.vbs

''''''''''''''''''''''''''''''''''''
''' Class ADODB
''''''''''''''''''''''''''''''''''''
Class ADODB
Dim ADOConnection

Private Sub Class_Initialize()
On Error Resume Next
Set ADOConnection = CreateObject("ADODB.Connection")
HandleError("Cannot create object 'ADODB.Connection' (ADODB.Class_Initialize).")
End Sub

Public Function Open(connectionString, provider, connectionTimeout)
On Error Resume Next
Open = false
if connectionString = "" Then
Err.Raise SCRIPT_EVENT_ID, "ADODB.Open()", "Argument 'connectionString' cannot be empty." , "", 0
End If
ADOConnection.ConnectionString = connectionString

if provider = "" Then
ADOConnection.Provider = "sqloledb"
Else
ADOConnection.Provider = provider
End If

if connectionTimeout &lt;= 0 Then
ADOConnection.ConnectionTimeout = 30
Else
ADOConnection.ConnectionTimeout = connectionTimeout
End If
HandleError("Cannot initialize ADODB connection (ADODB.Open).")

ADOConnection.Open()
if Err.number = 0 Then
Open = True
End If

End Function

Public Function ExecuteQuery(query)
On Error Resume Next
Set ExecuteQuery = ADOConnection.Execute(query)
End Function

Public Function Close()
On Error Resume Next
if Not IsNull(ADOConnection) Then
ADOConnection.Close()
HandleError("Cannot close ADODB connection (ADODB.Close).")
End If
End Function

Public Function HandleOpenConnectionErrorContinue(database, serverName, sqlInstanceName)
HandleOpenConnectionErrorContinue = true
if Err.number &lt;&gt; 0 Then
HandleOpenConnectionErrorContinue = false
Dim oError : Set oError = new Error
oError.Save()
Dim instanceIsRunning : instanceIsRunning = IsServiceRunning(sqlInstanceName)
On Error Resume Next
oError.Raise()
if ((Err.number and 65535) = 16389 or (Err.number and 65535) = 3661) and instanceIsRunning Then
Logger.LogError("Cannot login to database [" &amp; serverName &amp; "][" &amp; sqlInstanceName &amp; ":" &amp; database &amp; "] ")
Err.Clear
ElseIf (instanceIsRunning) Then
Logger.LogFormattedError("Cannot open ADODB connection. (Connection string: '" &amp; ADOConnection.ConnectionString &amp; "'.)")
Err.Clear
Else
Err.Clear
End If
On Error Goto 0
End If
End Function

Public Function HandleExecutionQueryErrorContinue(query, serverName, sqlInstanceName)
HandleExecutionQueryErrorContinue = true
if Err.number &lt;&gt; 0 Then
HandleExecutionQueryErrorContinue = false
Dim oError : Set oError = new Error
oError.Save()
Dim instanceIsRunning : instanceIsRunning = IsServiceRunning(sqlInstanceName)
On Error Resume Next
error.Raise()
if ((Err.number and 65535) = 16389 or (Err.number and 65535) = 3661) and instanceIsRunning Then
Logger.LogError("Cannot login to database [" &amp; serverName &amp; "][" &amp; sqlInstanceName &amp; ":" &amp; ADOConnection.DefaultDatabase &amp; "] ")
Err.Clear
ElseIf (instanceIsRunning) Then
Logger.LogFormattedError("Cannot execute query: '" &amp; query &amp; "'.")
Err.Clear
Else
Err.Clear
End If
On Error Goto 0
End If
End Function

Public Function IsServiceRunning(sInstance)
Dim sServiceName : sServiceName = GetSQLServiceName(sInstance)
Dim oService, sObjectString
sObjectString = "winmgmts:\\.\root\cimv2"

On Error Resume Next
Err.Clear
'We want to do our own error handling here. No WMIGetObject().
Set oService = GetObject(sObjectString &amp; ":Win32_Service.Name='" &amp; EscapeWQLString(sServiceName) &amp; "'")
If Err.Number &lt;&gt; 0 Then
IsServiceRunning = false
Else
If oService.State = "Running" Then
IsServiceRunning = true
Else
IsServiceRunning = false
End If
End If
Set oService = Nothing
On Error GoTo 0
End Function
End Class
'#Include File:GetDiskVolumeInformation.vbs

'''''''''''''''''''''''''''''''''''''
''' Assembling Volumes Collection '''
'''''''''''''''''''''''''''''''''''''
Const WMI_LINK = "winmgmts:{impersonationLevel=impersonate}!\\{0}\root\cimv2"
Const MOUNT_POINTS_QUERY = "select Directory, Volume from Win32_Mountpoint"
Const VOLUME_QUERY = "select DeviceID, Name, Caption, Label, FileSystem, Capacity, FreeSpace from Win32_Volume"
Const WMI_ERROR = "Can't get WMI object on "
Const MOUNT_POINT_ERROR = "Can't select Mount Point data from WMI object on "
Const DISK_VOLUME_ERROR = "Can't select Disk Volume data from WMI object on "
Const FIND_BY_DEVICEID_ERROR = "Couldn't find volume by DeviceID "

'Main class which is supposed to be used in external scripts
Class DiskVolumeInformation
Public MountPoints
Public Volumes

Public Default Function Initialize(serverName)
Set MountPoints = SortMountPoints(GetMountPoints(serverName))
Set Volumes = GetVolumes(serverName, MountPoints)
Set Initialize = Me
End Function
End Class

Class MountPoint
Public Name
Public Caption
Public DeviceID
End Class

Function GetMountPoints(serverName)
On Error Resume Next

Dim MountPoints : Set MountPoints = CreateObject("Scripting.Dictionary")

Dim objWMIService : Set objWMIService = GetObject(Replace(WMI_LINK, "{0}", serverName))
HandleError(WMI_ERROR &amp; serverName)
Dim colItems : Set colItems = objWMIService.ExecQuery(MOUNT_POINTS_QUERY)
HandleError(MOUNT_POINT_ERROR &amp; serverName)
Dim objItem
For Each objItem In colItems
Dim point : set point = new MountPoint
Dim dirStartIndex : dirStartIndex = InStr(objItem.Directory, """") + 1
Dim dirEndIndex : dirEndIndex = InStr(dirStartIndex, objItem.Directory, """")
Dim Directory
Directory = LCase(Replace(Mid(objItem.Directory, dirStartIndex, dirEndIndex - dirStartIndex), "\\", "\"))
point.Caption = Directory


Dim devStartIndex : dirStartIndex = InStr(objItem.Volume, """") + 1
Dim devEndIndex : dirEndIndex = InStr(dirStartIndex, objItem.Volume, """")
Dim DeviceID
DeviceID = Replace(Mid(objItem.Volume, dirStartIndex, dirEndIndex - dirStartIndex), "\\", "\")
point.DeviceID = DeviceID

point.Name = point.DeviceID &amp; point.Caption
MountPoints.Add point.Name, point
Next

Set GetMountPoints = MountPoints
End Function

Class DiskVolume
Public FileSystem
Public Capacity
Public FreeSpace
Public Name
Public DeviceID
Public Label
Public Paths()
Private pSize

Public Function AddPath(path)
pSize = pSize + 1
ReDim Preserve Paths(pSize)
Paths(pSize) = path
End Function

Private Sub Class_Initialize
pSize = -1
End Sub
End Class

Function GetVolumes(serverName, aMountPoints)
Dim Volumes : Set Volumes = CreateObject("Scripting.Dictionary")

Dim objWMIService : Set objWMIService = GetObject(Replace(WMI_LINK, "{0}", serverName))
HandleError(WMI_ERROR &amp; serverName)
Dim colItems : Set colItems = objWMIService.ExecQuery(VOLUME_QUERY)
HandleError(DISK_VOLUME_ERROR &amp; serverName)
Dim objItem
For Each objItem In colItems
Dim vol : set vol = new DiskVolume
vol.Capacity = objItem.Capacity
vol.FileSystem = objItem.FileSystem
vol.FreeSpace = objItem.FreeSpace
vol.Name = objItem.Name
vol.AddPath objItem.Caption
vol.DeviceID = objItem.DeviceID
vol.Label = objItem.Label
Volumes.Add vol.DeviceID, vol
Next

MergeMountPointsIntoVolumeList Volumes, aMountPoints

Set GetVolumes = Volumes
End Function

Function SearchVolumeCaption(aVolumes, aCaption)
Dim k
For Each k In aVolumes.Keys
Dim p
For p = 0 To UBound(aVolumes.Item(k).Paths)
If aVolumes.Item(k).Paths(p) = aCaption Then
SearchVolumeCaption = True
Exit Function
End If
Next
Next
SearchVolumeCaption = false
End Function

Function SearchVolumeDeviceID(aVolumes, aDeviceID)
Dim k
For Each k In aVolumes.Keys
If aVolumes.Item(k).DeviceID = aDeviceID Then
Set SearchVolumeDeviceID = aVolumes.Item(k)
Exit Function
End If
Next
Set SearchVolumeDeviceID = Nothing
End Function

Function MergeMountPointsIntoVolumeList(Volumes, MountPoints)
Dim key
For Each key in MountPoints.Keys
Dim Caption : Caption = MountPoints.Item(key).Caption
'Adding backslash in the end of the path is necessary for
'matching the path stored in volumes class, also it prevents
'invalid equality among folders with long composite names like
'"C:\Program Files" and "C:\Program"
If Right(Caption, 1) &lt;&gt; "\" Then
Caption = Caption &amp; "\"
End If

'Search for Mount Points which are not listed among Volumes
Dim found : found = SearchVolumeCaption(Volumes, Caption)
If Not found Then
'Search for the equivalent Volume
Dim equalVolume : Set equalVolume = SearchVolumeDeviceID(Volumes, MountPoints.Item(key).DeviceID)
HandleError(FIND_BY_DEVICEID_ERROR &amp; MountPoints.Item(key).DeviceID)
If Not equalVolume Is Nothing And Not IsNull(equalVolume) And Not IsEmpty(equalVolume) Then
equalVolume.AddPath Caption
End If
End If
Next
End Function

''''''''''''''''''''''''''''''''''''''''''''''''''''''
''' Sorting Mount Points descending by path length '''
''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function SortMountPoints(aMountPoints)
'Convert dictionary to array
Dim MPArray()
Dim i : i = 0
Dim key
For Each key in aMountPoints.Keys
ReDim Preserve MPArray(i)
Set MPArray(i) = aMountPoints.Item(key)
i = i + 1
Next

'Sorting array
Dim SortedArray : SortedArray = SortArray(MPArray)

'Converting back to dictionary
Set SortMountPoints = CreateObject("Scripting.Dictionary")
Dim a
For Each a in SortedArray
SortMountPoints.Add a.Caption, a
Next
End Function

Function SortArray(arr)
If UBound(arr) &lt; 1 Then
SortArray = arr
Exit Function
End If

Dim pivotIndex : pivotIndex = UBound(arr) 'Select last element as pivot
Dim pivot : Set pivot = arr(pivotIndex)
ReDim Preserve arr(UBound(arr) - 1) 'Remove pivot element
Dim longerList()
Dim shorterList()
Dim longerListSize : longerListSize = 0
Dim shorterListSize : shorterListSize = 0
'Put the elements with longer path than pivot to longerList
'and the elements with shorter path to shorterList
Dim a
For Each a in arr
If Len(a.Caption) &gt; Len(pivot.Caption) Then
ReDim Preserve longerList(longerListSize)
Set longerList(longerListSize) = a
longerListSize = longerListSize + 1
Else
ReDim Preserve shorterList(shorterListSize)
Set shorterList(shorterListSize) = a
shorterListSize = shorterListSize + 1
End If
Next

Dim sortedLess, sortedGreater
If longerListSize &gt; 0 Then
sortedLess = SortArray(longerList)
Else
sortedLess = longerList
End If

If shorterListSize &gt; 0 Then
sortedGreater = SortArray(shorterList)
Else
sortedGreater = shorterList
End If

SortArray = MergeArrays(sortedLess, longerListSize, pivot, sortedGreater, shorterListSize)
End Function

Function MergeArrays(lessArray, longerListSize, pivotNode, greaterArray, shorterListSize)
Dim arraySize : arraySize = longerListSize + shorterListSize
Dim ResultArray()
ReDim ResultArray(arraySize)
Dim i
For i = 0 To UBound(ResultArray)
If i &lt; longerListSize Then
Set ResultArray(i) = lessArray(i)
ElseIf i &gt; longerListSize Then
Set ResultArray(i) = greaterArray(i - longerListSize - 1)
Else
Set ResultArray(i) = pivotNode
End If
Next
MergeArrays = ResultArray
End Function
'#Include File:SQLFreeSpaceCalculator.vbs

''''''''''''''''''''''''''''''''''''
''' Class DBSpaceCalculator
''''''''''''''''''''''''''''''''''''
Class DBSpaceCalculator
Public FreeSpaceMB
Public FreeSpacePercent
Public FreeSpaceAutoGrowMB
Public FreeSpaceAutoGrowPercent
Public SizeMB
Public AllocatedFreeSpaceMB
Public AllocatedFreeSpacePercent
Public DiskFreeSpaceMB
Public DiskFreeSpacePercent
Public UsedSpaceMB
Public UsedSpacePercent
Public TotalSpaceMB
Public IsTotalAutoGrow
Private VolumeGrowthArray
Private DiskVolumesInfo

Private Sub Class_Initialize()
FreeSpaceMB = 0
FreeSpacePercent = 0
UsedSpaceMB = 0
SizeMB = 0
FreeSpaceAutoGrowMB = 0
FreeSpaceAutoGrowPercent = 0
AllocatedFreeSpaceMB = 0
AllocatedFreeSpacePercent = 0
DiskFreeSpaceMB = 0
DiskFreeSpacePercent = 0
UsedSpacePercent = 0
TotalSpaceMB = 0
IsTotalAutoGrow = false
Set VolumeGrowthArray = CreateObject("Scripting.Dictionary")
End Sub

Public Default Function Init(diskVolumesInformation)
Set DiskVolumesInfo = diskVolumesInformation
Dim key
For Each key in DiskVolumesInfo.Volumes.Keys
VolumeGrowthArray.Add DiskVolumesInfo.Volumes.Item(key).DeviceID, 0
Next
Set Init = Me
End Function

Private Function GetVolumeByPath(filePath)
Dim mpKey
For Each mpKey In DiskVolumesInfo.MountPoints.Keys
If InStr(LCase(filePath), LCase(DiskVolumesInfo.MountPoints.Item(mpKey).Caption)) &gt; 0 Then
Set GetVolumeByPath = DiskVolumesInfo.Volumes.Item(DiskVolumesInfo.MountPoints.Item(mpKey).DeviceID)
Exit Function
End If
Next
End Function

Private Function GetFreeSpaceDisk(filePath)
On Error Resume Next

Dim vol : Set vol = GetVolumeByPath(filePath)
If Not vol is Nothing And Not IsNull(vol) And Not IsEmpty(vol) Then
GetFreeSpaceDisk = vol.FreeSpace / 1024 / 1024
Exit Function
End If

Dim diskName : diskName = Left(filePath, 1)
Dim disk : Set disk = FSO.GetDrive(diskName)
HandleError("Cannot get object of disk '" &amp; diskName &amp; "'")
GetFreeSpaceDisk = disk.FreeSpace / 1024 / 1024
HandleError("Cannot get FreeSpace of disk '" &amp; diskName &amp; "'")
End Function

Public Function CalculateFreeSpace(dbFilesSet)
'On Error Resume Next

Dim GroupAvailableSpace : GroupAvailableSpace = 0
Dim GroupUsedSpace : GroupUsedSpace = 0
Dim GroupAvailableSpaceNoGrowth : GroupAvailableSpaceNoGrowth = 0
Dim GroupUsedSpaceNoGrowth : GroupUsedSpaceNoGrowth = 0

Do While Not dbFilesSet.EOF
Dim filePath : filePath = dbFilesSet("physical_name").Value

Dim fileSize : fileSize = CDbl(dbFilesSet("fileSize").Value)
Dim fileUsedSpace : fileUsedSpace = CDbl(dbFilesSet("fileUsed").Value)

GroupAvailableSpaceNoGrowth = GroupAvailableSpaceNoGrowth + fileSize
GroupUsedSpaceNoGrowth = GroupUsedSpaceNoGrowth + fileUsedSpace
GroupAvailableSpace = GroupAvailableSpace + fileSize
GroupUsedSpace = GroupUsedSpace + fileUsedSpace

Dim IsAutoGrow : IsAutoGrow = CBool(dbFilesSet("IsAutoGrow").Value = 1)
IsTotalAutoGrow = CBool(IsTotalAutoGrow Or IsAutoGrow)
if (IsAutoGrow) Then

Dim NumberGrowths : NumberGrowths = 0

Dim GrowthSpaceDisk : GrowthSpaceDisk = 0

Dim GrowthSpaceMaxSize : GrowthSpaceMaxSize = CDbl(1.79769313486232E307)
Dim fileMaxSize : fileMaxSize = CLng(dbFilesSet("fileMaxSize").Value)
Dim fileGrowth : fileGrowth = CLng(dbFilesSet("fileGrowth").Value)

Dim isPercentGrowth : isPercentGrowth = dbFilesSet("isPercentGrowth").Value

if Not isPercentGrowth Then 'FileGrowth not in Percent
fileGrowth = fileGrowth / 128
Else
fileGrowth = fileGrowth / 100
End If


if fileMaxSize &lt;&gt; -1 Then 'FileMaxSize Not Unlimited
'when the FileSize approaches the MaxSize, a large FileGrowth value can cause an error
'if the file tries to grow past the MaxSize value.
'calculate actual growth capacity
if isPercentGrowth Then 'FileGrowth in Percent
NumberGrowths = Fix(Log(fileMaxSize / fileSize) / Log(1 + fileGrowth))
GrowthSpaceMaxSize = (fileSize * ((1 + fileGrowth) ^ NumberGrowths)) - fileSize
Else
GrowthSpaceMaxSize = Fix((fileMaxSize - fileSize) / fileGrowth) * fileGrowth
End If
End If

Dim FreeSpaceDisk : FreeSpaceDisk = GetFreeSpaceDisk(filePath)

'when the FileSize approaches the limits of the logical disk, a large FileGrowth
'value can cause an error if the file tries to grow past the physical limit
'calculate actual growth capacity on disk
if isPercentGrowth Then 'FileGrowth in Percent
NumberGrowths = Fix(Log((FreeSpaceDisk + fileSize) / fileSize) / Log(1 + fileGrowth))
GrowthSpaceDisk = (fileSize * ((1 + fileGrowth) ^ NumberGrowths)) - fileSize
Else
GrowthSpaceDisk = Fix(FreeSpaceDisk / fileGrowth) * fileGrowth
End If

'with auto grow the growth allowed for a file with a max size is the minimum
'of either up to the max size or up to the limits of the logical drive.
'With max size unlimited, the growth allowed is not limited except by the limits of the logical drive
Dim GrowthAllowed : GrowthAllowed = GrowthSpaceDisk
if GrowthSpaceMaxSize &lt; GrowthSpaceDisk Then
GrowthAllowed = GrowthSpaceMaxSize
End If

'add growth allowed for this file to hosting logical drive up to the free disk space capacity.
Dim LogicalDriveGrowth : LogicalDriveGrowth = GetLogicalDriveGrowth(filePath)
If LogicalDriveGrowth + GrowthAllowed &gt; FreeSpaceDisk Then
SetLogicalDriveGrowth filePath, FreeSpaceDisk
Else
SetLogicalDriveGrowth filePath, LogicalDriveGrowth + GrowthAllowed
End If
End If
dbFilesSet.MoveNext
Loop

Dim logicalDriveGrowthKey
for each logicalDriveGrowthKey in VolumeGrowthArray
GroupAvailableSpace = GroupAvailableSpace + VolumeGrowthArray.Item(logicalDriveGrowthKey)
Next

Me.UsedSpaceMB = GroupUsedSpace
Me.FreeSpaceMB = GroupAvailableSpace - GroupUsedSpace
if Me.FreeSpaceMB &lt; 0 Then
Me.FreeSpaceMB = 0
End If

Me.FreeSpacePercent = (GroupAvailableSpace - GroupUsedSpace) / GroupAvailableSpace * 100
if Me.FreeSpacePercent &lt; 0 Then
Me.FreeSpacePercent = 0
End If

Me.SizeMB = GroupAvailableSpaceNoGrowth

Me.FreeSpaceAutoGrowMB = GroupAvailableSpaceNoGrowth - GroupUsedSpaceNoGrowth
if Me.FreeSpaceAutoGrowMB &lt; 0 Then
Me.FreeSpaceAutoGrowMB = 0
End If

Me.FreeSpaceAutoGrowPercent = (GroupAvailableSpaceNoGrowth - GroupUsedSpaceNoGrowth) / GroupAvailableSpaceNoGrowth * 100
if Me.FreeSpaceAutoGrowPercent &lt; 0 Then
Me.FreeSpaceAutoGrowPercent = 0
End If

Me.AllocatedFreeSpaceMB = Me.SizeMB - Me.UsedSpaceMB
if Me.AllocatedFreeSpaceMB &lt; 0 Then
Me.AllocatedFreeSpaceMB = 0
End If

Me.DiskFreeSpaceMB = Me.FreeSpaceMB - Me.AllocatedFreeSpaceMB
if Me.DiskFreeSpaceMB &lt; 0 Then
Me.DiskFreeSpaceMB = 0
End If

Me.TotalSpaceMB = Me.DiskFreeSpaceMB + Me.AllocatedFreeSpaceMB + Me.UsedSpaceMB

Me.AllocatedFreeSpacePercent = (Me.AllocatedFreeSpaceMB / TotalSpaceMB) * 100

Me.DiskFreeSpacePercent = (Me.DiskFreeSpaceMB / TotalSpaceMB) * 100

Me.UsedSpacePercent = (Me.UsedSpaceMB / TotalSpaceMB) * 100

End Function

Function GetLogicalDriveGrowth(filePath)
Dim vol : Set vol = GetVolumeByPath(filePath)
If Not IsNull(vol) And Not IsEmpty(vol) Then
GetLogicalDriveGrowth = VolumeGrowthArray.Item(vol.DeviceID)
End If
End Function

Function SetLogicalDriveGrowth(filePath, value)
Dim vol : Set vol = GetVolumeByPath(filePath)
If Not IsNull(vol) And Not IsEmpty(vol) Then
VolumeGrowthArray.Item(vol.DeviceID) = value
End If
End Function

End Class

'#Include File:GetSQLDBFreeSpace.vbs

Const DB_STATE_EMERGENCYMODE = 32768
Const DB_STATE_LOADING = 22
Const DB_STATE_NORMAL = 0
Const DB_STATE_OFFLINE = 512
Const DB_STATE_RECOVERING = 192
Const DB_STATE_STANDBY = 1024
Const DB_STATE_SUSPECT = 256

Const SCRIPT_EVENT_ID = 4001

Function Main()
On Error Resume Next
Logger.LogDebug("Start...")
if WScript.Arguments.Count() &lt;&gt; 4 Then
WScript.Quit()
End If
Dim connectionStr : connectionStr = WScript.Arguments(0)
Dim serverName : serverName = WScript.Arguments(1)
Dim instanceName : instanceName = WScript.Arguments(2)
Dim TcpPort : TcpPort = WScript.Arguments(3)

Logger.LogDebug("connectionStr = " &amp; connectionStr &amp; "; ServerName = " &amp; serverName &amp; "; instanceName = " &amp; instanceName)

GetAllDbFreeSpace connectionStr, serverName, instanceName, TcpPort

logger.LogDebug("End...")
End Function

Public Function GetSQLServiceName(sInstance)
If sInstance = "MSSQLSERVER" Then
GetSQLServiceName = "MSSQLSERVER"
Else
GetSQLServiceName = "MSSQL$" &amp; sInstance
End If
End Function

'The function returns service or "Unknown" state
'Input:
' server - compute name
' service - system service name
'Output:
' service state or "Unknown" state
Function GetServiceState( sTargetComputer, sServiceName)
On Error Resume Next

Dim sNamespace, sQuery, oWMI, objClasses, sState
sNamespace = "winmgmts://" &amp; sTargetComputer &amp; "/root/cimv2"
sQuery = "SELECT State FROM Win32_Service where Name = """ &amp; EscapeWQLString(sServiceName) &amp; """"

Set oWMI = GetObject(sNamespace)
Set objClasses = oWMI.ExecQuery(sQuery)

if objClasses.Count &gt;= 1 Then
sState = objClasses.ItemIndex(0).Properties_.Item("State")
End If

If Err.number &lt;&gt; 0 Or objClasses.Count = 0 Then
sState = "Unknown"
End If

Err.Clear
GetServiceState = sState
End Function

''' Returns -1: If DB is not in AlwaysOn
''' Returns 0: If DB is in AlwaysOn and replica allow connections is NO
''' Returns 1: If DB is in AlwaysOn and replica allow connections is YES
Function AlwaysOnReplicaAllowConnections(aDbConnection, aDatabaseID)
AlwaysOnReplicaAllowConnections = -1
Dim query : query = " SELECT columns.id, " &amp; _
" CASE WHEN OBJECT_ID('sys.availability_replicas') IS NOT NULL THEN 1 ELSE 0 END AS HasAlwaysOn " &amp; _
" FROM sys.syscolumns columns where name = 'replica_id' and id = OBJECT_ID('sys.databases')"

Dim result : Set result = aDbConnection.ExecuteQuery(query)
If Not result.EOF Then
If result("HasAlwaysOn").Value = 1 Then
query = " SELECT d.name, d.database_id, " &amp; _
" CASE WHEN d.replica_id IS NULL THEN 0 ELSE 1 END AS is_replica, " &amp; _
" ar.secondary_role_allow_connections " &amp; _
" FROM sys.databases d " &amp; _
" JOIN sys.availability_replicas ar on d.replica_id = ar.replica_id " &amp; _
" JOIN sys.servers s ON s.name = ar.replica_server_name AND s.server_id = 0 /*local server*/" &amp; _
" WHERE d.database_id = " &amp; aDatabaseID
Set result = aDbConnection.ExecuteQuery(query)
If Not result.EOF Then
If result("is_replica").Value = 1 Then
AlwaysOnReplicaAllowConnections = 1
if (result("secondary_role_allow_connections").Value &lt;= 1) Then
AlwaysOnReplicaAllowConnections = 0
Else
AlwaysOnReplicaAllowConnections = 1
End If
End If
End If
End If
End If
End Function

Function GetAllDbFreeSpace(connectionStr, serverName, instanceName, sTcpPort)
On Error Resume Next
Dim opsMgrAPI
Dim tcp : tcp = sTcpPort
Dim dbMasterConnection
Dim listDatabases
Dim query : query = "SELECT name, database_id FROM sys.databases " &amp; _
" WHERE state = 0 AND collation_name is not null " &amp; _
" AND source_database_id IS NULL AND is_read_only = 0"

Set opsMgrAPI = new OpsMgrAPI
Set dbMasterConnection = new ADODB

Dim serviceName , state
serviceName = GetSQLServiceName(instanceName)
state = GetServiceState(serverName, serviceName)
if (state &lt;&gt; "Running") And (state &lt;&gt; "Unknown") Then
Dim bg
Set bg = opsMgrAPI.scriptAPI.CreateTypedPropertyBag(2)
opsMgrAPI.scriptAPI.AddItem(bg)
opsMgrAPI.scriptAPI.ReturnItems()
Exit Function
End If


Dim strProv : strProv = BuildConnectionStringWithPort(connectionStr, "master", tcp)

Err.Clear
Dim res : res = dbMasterConnection.Open(strProv, "sqloledb", 3)
'get fresh tcp port and try to connect again
if 0 &lt;&gt; Err.number then
Err.Clear
tcp = GetTcpPort(connectionStr)
strProv = BuildConnectionStringWithPort(connectionStr, "master", tcp)
res = dbMasterConnection.Open(strProv, "sqloledb", 30)

if 0 &lt;&gt; Err.number then
dbMasterConnection.HandleOpenConnectionErrorContinue "master", serverName, instanceName
Set propertyBag = opsMgrAPI.scriptAPI.CreateTypedPropertyBag(2)
opsMgrAPI.scriptAPI.AddItem(propertyBag)
opsMgrAPI.scriptAPI.ReturnItems()
Exit Function
end if
end if
Set listDatabases = dbMasterConnection.ExecuteQuery(query)
if dbMasterConnection.HandleExecutionQueryErrorContinue(query, serverName, instanceName) Then
Dim diskVolumesInfo : Set diskVolumesInfo = (new DiskVolumeInformation)(serverName)
Do While Not listDatabases.EOF
Dim databaseName : databaseName = listDatabases("name").Value
Dim databaseID : databaseID = listDatabases("database_id").Value
Dim dbConnection : Set dbConnection = new ADODB
if dbConnection.Open (BuildConnectionStringWithPort(connectionStr, databaseName, tcp), "sqloledb", 30) Then
Dim propertyBag
Set propertyBag = opsMgrAPI.scriptAPI.CreateTypedPropertyBag(2)
''==================================
'' Calculate total space for DB (type = 0 - data files)
''==================================
query = "SET NOCOUNT ON " &amp; vbCrLf &amp; _
"SELECT size / 128.0 as fileSize, " &amp; vbCrLf &amp; _
" FILEPROPERTY(name, 'SpaceUsed') / 128.0 as fileUsed," &amp; vbCrLf &amp; _
" CASE WHEN max_size = -1 OR max_size = 268435456 THEN -1 ELSE max_size / 128 END as fileMaxSize," &amp; vbCrLf &amp; _
" CASE WHEN growth = 0 THEN 0 ELSE 1 END as IsAutoGrow, " &amp; vbCrLf &amp; _
" is_percent_growth as isPercentGrowth, " &amp; vbCrLf &amp; _
" growth as fileGrowth, " &amp; vbCrLf &amp; _
" physical_name " &amp; vbCrLf &amp; _
" FROM sys.master_files WITH (NOLOCK) " &amp; vbCrLf &amp; _
" WHERE type = 0 AND is_read_only = 0 " &amp; vbCrLf &amp; _
" AND database_id = " &amp; databaseID
Dim listFiles : Set listFiles = dbConnection.ExecuteQuery(query)
if dbConnection.HandleExecutionQueryErrorContinue(query, serverName, instanceName) Then
Dim spaceCalculator : Set spaceCalculator = (new DBSpaceCalculator)(diskVolumesInfo)
spaceCalculator.CalculateFreeSpace(listFiles)

Call propertyBag.AddValue("Database", databaseName)
Call propertyBag.AddValue("DBSizeMB", spaceCalculator.SizeMB)
Call propertyBag.AddValue("DBFreeSpaceMB", spaceCalculator.FreeSpaceMB)
Call propertyBag.AddValue("DBFreeSpacePercent", spaceCalculator.FreeSpacePercent)

Call propertyBag.AddValue("DBAllocatedFreeSpacePercent", spaceCalculator.AllocatedFreeSpacePercent)
Call propertyBag.AddValue("DBAllocatedFreeSpaceMB", spaceCalculator.AllocatedFreeSpaceMB)
Call propertyBag.AddValue("DBUsedSpacePercent", spaceCalculator.UsedSpacePercent)
Call propertyBag.AddValue("DBUsedSpaceMB", spaceCalculator.UsedSpaceMB)
If spaceCalculator.IsTotalAutoGrow Then
Call propertyBag.AddValue("DBDiskFreeSpacePercent", spaceCalculator.DiskFreeSpacePercent)
Call propertyBag.AddValue("DBDiskFreeSpaceMB", spaceCalculator.DiskFreeSpaceMB)
Else
'' You should check DBDiskFreeSpaceMB and DBDiskFreeSpacePercent value in ConditionDetection filter
Call propertyBag.AddValue("DBDiskFreeSpacePercent", -1)
Call propertyBag.AddValue("DBDiskFreeSpaceMB", -1)
End If
End If

''==================================
'' Calculate space of log files for DB (type = 1 - log files)
''==================================
query = "SET NOCOUNT ON " &amp; vbCrLf &amp; _
"SELECT size / 128.0 as fileSize, " &amp; vbCrLf &amp; _
" FILEPROPERTY(name, 'SpaceUsed') / 128.0 as fileUsed," &amp; vbCrLf &amp; _
" CASE WHEN max_size = -1 OR max_size = 268435456 THEN -1 ELSE max_size / 128 END as fileMaxSize," &amp; vbCrLf &amp; _
" CASE WHEN growth = 0 THEN 0 ELSE 1 END as IsAutoGrow, " &amp; vbCrLf &amp; _
" is_percent_growth as isPercentGrowth, " &amp; vbCrLf &amp; _
" growth as fileGrowth, " &amp; vbCrLf &amp; _
" physical_name " &amp; vbCrLf &amp; _
" FROM sys.master_files WITH (NOLOCK) " &amp; vbCrLf &amp; _
" WHERE type = 1 AND is_read_only = 0 " &amp; vbCrLf &amp; _
" AND database_id = " &amp; databaseID
Set listFiles = dbConnection.ExecuteQuery(query)
if dbConnection.HandleExecutionQueryErrorContinue(query, serverName, instanceName) Then
spaceCalculator.CalculateFreeSpace(listFiles)

Call propertyBag.AddValue("DBLogSizeMB", spaceCalculator.SizeMB)
Call propertyBag.AddValue("DBLogFreeSpaceMB", spaceCalculator.FreeSpaceMB)
Call propertyBag.AddValue("DBLogFreeSpacePercent", spaceCalculator.FreeSpacePercent)
End If

dbConnection.Close()
opsMgrAPI.scriptAPI.AddItem(propertyBag)
Else
Dim replicaAllowConnections : replicaAllowConnections = AlwaysOnReplicaAllowConnections(dbMasterConnection, databaseID)
If replicaAllowConnections &lt;&gt; 0 Then
dbConnection.HandleOpenConnectionErrorContinue databaseName, serverName, instanceName
End If
End If
listDatabases.MoveNext
Loop
End If
dbMasterConnection.Close()
opsMgrAPI.scriptAPI.ReturnItems()
End Function
</Script></ScriptBody>
<TimeoutSeconds>$Config/TimeoutSeconds$</TimeoutSeconds>
</DataSource>
<ConditionDetection ID="PerfMapper" TypeID="SystemPerf!System.Performance.DataGenericMapper">
<ObjectName>$Config/ObjectName$</ObjectName>
<CounterName>$Config/CounterName$</CounterName>
<InstanceName>$Config/InstanceName$</InstanceName>
<Value>$Config/Value$</Value>
</ConditionDetection>
<ConditionDetection ID="InstanceFilter" TypeID="System!System.ExpressionFilter">
<Expression>
<SimpleExpression>
<ValueExpression>
<XPathQuery Type="String">Property[@Name='Database']</XPathQuery>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value Type="String">$Config/DatabaseName$</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
</ConditionDetection>
</MemberModules>
<Composition>
<Node ID="PerfMapper">
<Node ID="InstanceFilter">
<Node ID="DS"/>
</Node>
</Node>
</Composition>
</Composite>
</ModuleImplementation>
<OutputType>SystemPerf!System.Performance.Data</OutputType>
</DataSourceModuleType>