Disk Volumes State Provider

Microsoft.SQLServerAppliance.BI.VolumesState.DataSource (DataSourceModuleType)

Disk volumes state provider.

Element properties:

TypeDataSourceModuleType
IsolationAny
AccessibilityPublic
RunAsMicrosoft.SQLServerAppliance.BI.MonitoringProfile
OutputTypeSystem.PropertyBagData

Member Modules:

ID Module Type TypeId RunAs 
DS DataSource System.CommandExecuterPropertyBagSource Default

Overrideable Parameters:

IDParameterTypeSelectorDisplay NameDescription
IntervalSecondsint$Config/IntervalSeconds$Frequency (seconds)
TimeoutSecondsint$Config/TimeoutSeconds$Timeout (seconds)

Source Code:

<DataSourceModuleType ID="Microsoft.SQLServerAppliance.BI.VolumesState.DataSource" Accessibility="Public" RunAs="BIDisco!Microsoft.SQLServerAppliance.BI.MonitoringProfile">
<Configuration>
<xsd:element name="IntervalSeconds" type="xsd:int"/>
<xsd:element name="TargetComputerName" type="xsd:string"/>
<xsd:element name="TimeoutSeconds" type="xsd:integer"/>
</Configuration>
<OverrideableParameters>
<OverrideableParameter ID="IntervalSeconds" ParameterType="int" Selector="$Config/IntervalSeconds$"/>
<OverrideableParameter ID="TimeoutSeconds" ParameterType="int" Selector="$Config/TimeoutSeconds$"/>
</OverrideableParameters>
<ModuleImplementation>
<Composite>
<MemberModules>
<DataSource ID="DS" TypeID="System!System.CommandExecuterPropertyBagSource">
<IntervalSeconds>$Config/IntervalSeconds$</IntervalSeconds>
<ApplicationName>%windir%\system32\cscript.exe</ApplicationName>
<WorkingDirectory/>
<CommandLine>//nologo $file/VolumesStateProvider.vbs$ $Config/TargetComputerName$</CommandLine>
<TimeoutSeconds>$Config/TimeoutSeconds$</TimeoutSeconds>
<RequireOutput>true</RequireOutput>
<Files>
<File>
<Name>VolumesStateProvider.vbs</Name>
<Contents><Script>
' ##### ..\Scripts\Common\Common.vbs
Option Explicit
SetLocale("en-us")

Const DEBUG_MODE = false
Const DEBUG_SCRIPT_EVENT_ID = 4201

Const ManagementGroupName = "$Target/ManagementGroup/Name$"


Sub HandleError(ByVal customMessage)
Dim logger
If Err.number &lt;&gt; 0 Then
Set logger = new ScriptLogger
logger.LogError(customMessage)
Wscript.Quit 0
End If
End Sub

Sub HandleErrorInDiscovery(ByVal customMessage, ByRef oDiscovery, ByRef oAPI)
Dim logger
If Err.number &lt;&gt; 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 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 = "Managegement Group: " + ManagementGroupName + ". 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 message, ByVal eventID)
if DEBUG_MODE Then
WScript.StdOut.WriteLine message
End If
LogEvent message, WARNING_EVENT_TYPE, eventID
End Function

Public Function LogError(ByVal customMessage)
Dim message
If Err.number &lt;&gt; 0 Then
message = Replace(" Error Number: #P1# " &amp; VbCrLf &amp; " Description: #P2# ", "#P1#", CStr(Err.number and 65535) )
message = Replace(message, "#P2#", Err.Description )
message = customMessage &amp; VbCrLf &amp; message &amp; VbCrLf
if DEBUG_MODE Then
WScript.StdOut.WriteLine message
End If
LogEvent message, ERROR_EVENT_TYPE, SCRIPT_EVENT_ID
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
' ##### Scripts\VolumesStateProvider.vbs
On Error Resume Next

'Event Id reserved by SQL Appliance MP for errors
Const SCRIPT_EVENT_ID = 4200
Const SYSTEM_DISK_SIZE = 314572800 '1 megabyte = 1048576 byte 300 megabyte = 1048576 * 300
Const WMI_OBJECT_NOT_FOUND = 4098 'WMI Error number when object not found

Dim targetComputer

Call Main()

'Execute WMI query and return WMIObjectSet
Function WMIExecQuery(ByRef objWMIService, ByVal sQuery)
On Error Resume Next
Dim oWMI, oQuery

Set oQuery = objWMIService.ExecQuery(sQuery)
Call HandleError("Cannot run WMI query")

Set WMIExecQuery = oQuery
End Function

Sub Main()
On Error Resume Next

Dim oAPI, oBag
Dim objWMIService
Dim oWmiDiskE, oWmiDiskSet, oWmiDisk
Dim nAllUsedSpace, nDiskESize
Dim oParams
Set oParams = WScript.Arguments

'Read computer name from parametrs
targetComputer = oParams(0)
Call HandleError("Cannot read target computer name from params")

'Get WMI object Win32_LogicalDisk where DeviceID='E:'

Set objWMIService = GetObject("winmgmts:\\" &amp; targetComputer &amp; "\root\cimv2")
Call HandleError("WMI problems. Cannot connect to winmgmts:\\" &amp; targetComputer &amp; "\root\cimv2")
Set oWmiDiskE = objWMIService.Get("Win32_LogicalDisk.DeviceID='E:'")
'Error with err.number = 4098 rased when 'object not found'. We do not need handle errors when disk E: is not exists.
'If disk E: is not exist then this situation is normal, just finish script
if (CInt(Err.number and 65535) = WMI_OBJECT_NOT_FOUND ) or IsEmpty(oWmiDiskE) Then
WScript.Quit 0
End If
Call HandleError("Cannot get WMI data of disks E")

'convert volume size to double
nDiskESize = Cdbl(oWmiDiskE.Size)

'Get DeviceID, Free Space amd Total Size for C: and D: volumes (return Win32_LogicalDisk)
'DriveType=3 is Local Disk
Set oWmiDiskSet = WMIExecQuery(objWMIService, "select DeviceID, FreeSpace, Size from Win32_LogicalDisk where DriveType=3 and (DeviceID='C:' or DeviceID='D:') and FileSystem != null")

Call HandleError("Cannot get WMI data of disks")

'If some disk from c or d is absent, we need rase warning in event log and finish script
If oWmiDiskSet.Count &lt; 2 Then
Dim logger
Set logger = new ScriptLogger
Call logger.LogWarning("Expected volume (C: or D:) is missed or not formatted", SCRIPT_EVENT_ID)
WScript.Quit 0
End If

nAllUsedSpace = 0

'Calculate sum of used space on c and d disks
For Each oWmiDisk in oWmiDiskSet
nAllUsedSpace = nAllUsedSpace + (Cdbl(oWmiDisk.Size) - Cdbl(oWmiDisk.FreeSpace))'need convert all values of WMI objects to double
Next

'add size of hidden volume "System" 300 Mbyte to result
nAllUsedSpace = nAllUsedSpace + SYSTEM_DISK_SIZE

Set oAPI = CreateObject("MOM.ScriptAPI")
Call HandleError("Cannot create MOM.ScriptAPI object")

Set oBag = oAPI.CreatePropertyBag()
Call HandleError("Cannot create MOM.ScriptAPI.PropertyBug object")

'nDiskESize - size of disk E
'nAllUsedSpace - sum of used space on c+d+r disks
If (nDiskESize &lt; nAllUsedSpace) Then
Call oBag.AddValue("BackupVolumeSizeInsufficient", "true")
Else
Call oBag.AddValue("BackupVolumeSizeInsufficient", "false")
End If

Call oAPI.AddItem(oBag)
Call oAPI.ReturnItems()
End Sub
</Script></Contents>
</File>
</Files>
</DataSource>
</MemberModules>
<Composition>
<Node ID="DS"/>
</Composition>
</Composite>
</ModuleImplementation>
<OutputType>System!System.PropertyBagData</OutputType>
</DataSourceModuleType>