Hyper-V Disk Partition Space Provider DataSource Module Type

Microsoft.Windows.HyperV.DiskPartitionSpaceProviderDataSourceModule (DataSourceModuleType)

Microsoft Windows Hyper-V Disk Partition Space Provider DataSource Module Type

Element properties:

TypeDataSourceModuleType
IsolationAny
AccessibilityPublic
RunAsSystem.PrivilegedMonitoringAccount
OutputTypeSystem.PropertyBagData

Member Modules:

ID Module Type TypeId RunAs 
Scheduler DataSource System.SimpleScheduler Default
Script ProbeAction Microsoft.Windows.ScriptPropertyBagProbe Default
Filter ConditionDetection System.ExpressionFilter Default

Overrideable Parameters:

IDParameterTypeSelectorDisplay NameDescription
IntervalSecondsint$Config/IntervalSeconds$Interval SecondsInterval Seconds
TimeoutSecondsint$Config/TimeoutSeconds$Timeout SecondsTimeout Seconds
SyncTimestring$Config/SyncTime$Synchronization TimeSynchronization Time

Source Code:

<DataSourceModuleType ID="Microsoft.Windows.HyperV.DiskPartitionSpaceProviderDataSourceModule" Accessibility="Public" RunAs="System!System.PrivilegedMonitoringAccount" Batching="false">
<Configuration>
<xsd:element minOccurs="1" name="IntervalSeconds" type="xsd:int"/>
<xsd:element minOccurs="1" name="TimeoutSeconds" type="xsd:integer"/>
<xsd:element minOccurs="0" name="SyncTime" type="xsd:string"/>
</Configuration>
<OverrideableParameters>
<OverrideableParameter ID="IntervalSeconds" Selector="$Config/IntervalSeconds$" ParameterType="int"/>
<OverrideableParameter ID="TimeoutSeconds" Selector="$Config/TimeoutSeconds$" ParameterType="int"/>
<OverrideableParameter ID="SyncTime" Selector="$Config/SyncTime$" ParameterType="string"/>
</OverrideableParameters>
<ModuleImplementation Isolation="Any">
<Composite>
<MemberModules>
<DataSource ID="Scheduler" TypeID="System!System.SimpleScheduler">
<IntervalSeconds>$Config/IntervalSeconds$</IntervalSeconds>
<SyncTime>$Config/SyncTime$</SyncTime>
</DataSource>
<ProbeAction ID="Script" TypeID="Windows!Microsoft.Windows.ScriptPropertyBagProbe">
<ScriptName>GetDiskPartitionSpace.vbs</ScriptName>
<Arguments>$Target/Host/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/PrincipalName$</Arguments>
<ScriptBody><Script>
'Copyright (c) Microsoft Corporation. All rights reserved.

Option Explicit

const MEGABYTE = 1048576

Call Main

Class DiskSpaceMonitoring
Public Monitor
Public TotalSpace
Public UsedSpace
Public FreeSpace
End Class

Function GetFreeDiskSpace(ByVal diskType, ByVal partitionPath, ByVal oFile)
Dim oDrive, driveLetter, diskMonitoring

Set diskMonitoring = new DiskSpaceMonitoring
diskMonitoring.TotalSpace = 0
diskMonitoring.UsedSpace = 0
diskMonitoring.FreeSpace = 0
diskMonitoring.Monitor = "false"

If (IsNull(partitionPath) = False And partitionPath &lt;&gt; "") Then
diskMonitoring.Monitor = "true"
On Error Resume Next
' Set the drive letter
driveLetter = oFile.GetDriveName(partitionPath)
If (Err.Number &lt;&gt; 0) Then
ThrowScriptError "Invalid Partition Path in " &amp; GetScriptName &amp; ".", Err
End If

' Get the drive
Set oDrive = oFile.GetDrive(driveLetter)
If (Err.Number &lt;&gt; 0 Or (diskType &lt;&gt; "3" And diskType &lt;&gt; "4")) Then
' Set monitoring off for clustering
If (Err.Number = 68 Or diskType &lt;&gt; "3" Or diskType &lt;&gt; "4") Then
diskMonitoring.Monitor = "false"
Else
ThrowScriptError "Drive does not exist in " &amp; GetScriptName &amp; ".", Err
End If
Else
' Get the disk space
diskMonitoring.TotalSpace = CLng(oDrive.TotalSize/MEGABYTE)
diskMonitoring.FreeSpace = CLng(oDrive.FreeSpace/MEGABYTE)
diskMonitoring.UsedSpace = CLng(diskMonitoring.TotalSpace - diskMonitoring.FreeSpace)
End If

On Error Goto 0
End If

Set GetFreeDiskSpace = diskMonitoring
End Function


Function CalculateUsedPerc(ByVal UsedSpace, ByVal TotalSpace)
Dim UsedSpacePerc

UsedSpacePerc = (UsedSpace * 100)/TotalSpace
CalculateUsedPerc = FormatNumber(UsedSpacePerc,2)
End Function

' Main Subroutine
Sub Main
SetLocale("en-us")
InitializeCommon(1000)

' Check Arguments
Dim oArgs
Set oArgs = WScript.Arguments
If oArgs.Count &lt; 1 Then
ThrowScriptError "Invalid parameters passed to " &amp; GetScriptName &amp; ".", Null
End If

' Process Arguments:
' ComputerIdentity
Dim ComputerIdentity
ComputerIdentity = oArgs(0)

' Create PropertyBag object
Dim oAPI, oPropertyBag
Set oAPI = MOMCreateObject("MOM.ScriptAPI")

' Set the file objects
Dim oFile
Set oFile = MOMCreateObject("Scripting.FileSystemObject")
If IsObjectUnallocated(oFile) = False Then

'Check for presence of Virtualization namespace in WMI
Dim oWMIService, errorNum
On Error Resume Next
Set oWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" &amp; ComputerIdentity &amp; "\root\virtualization")
errorNum = Err.Number
On Error Goto 0

If (errorNum = 0) Then
' Get the Virtual Machine object
Dim oVirtualMachine, oVMList
Set oVMList = oWMIService.ExecQuery("SELECT Name, ElementName FROM MSVM_ComputerSystem WHERE Name &lt;&gt; '" + GetHostComputerName() + "'")
If (IsListEmpty(oVMList) = False) Then
For each oVirtualMachine in oVMList
If IsObjectUnallocated(oVirtualMachine) = False Then
Dim oVirtualDriveList, oVirtualDrive, diskMonitoring
' Set property bag
Set oPropertyBag = oAPI.CreatePropertyBag()
oPropertyBag.AddValue "Name", oVirtualMachine.Name

' Get VHD Service instance
Dim oVHDService, oVHDServiceList
Set oVHDServiceList = oWMIService.ExecQuery("SELECT * FROM Msvm_ImageManagementService")
If (IsListEmpty(oVHDServiceList) = False) Then
Set oVHDService = oVHDServiceList.ItemIndex(0)
End If

' Get all Virtual Drives of the Virtual Machine
oVirtualDriveList = GetVirtualDrives(oVirtualMachine, oVHDService)
If (IsObjectUnallocated(oVirtualDriveList) = False) Then
For Each oVirtualDrive in oVirtualDriveList
If (IsObjectUnallocated(oVirtualDrive) = False) Then
' Get disk information and add it to the property bag
Set diskMonitoring = GetFreeDiskSpace(oVirtualDrive.DriveType, oVirtualDrive.ImageFile, oFile)
If (IsObjectUnallocated(diskMonitoring) = False) Then
oPropertyBag.AddValue oVirtualDrive.DeviceId &amp; ".VHDName", CStr(oVirtualDrive.Name)
oPropertyBag.AddValue oVirtualDrive.DeviceId &amp; ".UsedSpacePercent", CStr(CalculateUsedPerc(diskMonitoring.UsedSpace, diskMonitoring.TotalSpace))
oPropertyBag.AddValue oVirtualDrive.DeviceId &amp; ".TotalSpace", CStr(diskMonitoring.TotalSpace)
oPropertyBag.AddValue oVirtualDrive.DeviceId &amp; ".FreeSpace", CStr(diskMonitoring.FreeSpace)
oPropertyBag.AddValue oVirtualDrive.DeviceId &amp; ".UsedSpace", CStr(diskMonitoring.UsedSpace)
oPropertyBag.AddValue oVirtualDrive.DeviceId &amp; ".Monitor", diskMonitoring.Monitor
End If
End If
Next
End If

' Add propertybag to API
oAPI.AddItem(oPropertyBag)
End If
Next
End If
Else
Err.Clear
End If

End If
Call oAPI.ReturnItems
End Sub

'Copyright (c) Microsoft Corporation. All rights reserved.


' Virtual Network Adapter class
Class VirtualNetworkAdapter
Public DeviceId
Public Name
Public ConnectedNetworkId
Public ConnectedNetworkName
End Class


' Virtual Drive class
Class VirtualDrive
Public DeviceId
Public Name
Public DriveType
Public ImageFile
Public ConnectedControllerName
End Class


' Function to get all Virtual Network Adapters
Function GetVirtualNetworkAdapters(ByVal oVirtualMachine, ByVal oWMIService)
' Get network adapter list related to the virtual machine
Dim oWMIResult, oWMIObj, oNetworkAdapterList(), oNetworkAdapter, instanceCount, microsoftLength
microsoftLength = 10
instanceCount = 0
Set oWMIResult = oWMIService.ExecQuery("SELECT Name, ElementName FROM MSVM_VMLanEndPoint WHERE SystemName='" &amp; oVirtualMachine.Name &amp; "'")
If IsListEmpty(oWMIResult) = False Then
For Each oWMIObj in oWMIResult
' Create an instance of Network Adapter
ReDim Preserve oNetworkAdapterList(instanceCount+1)
Set oNetworkAdapter = New VirtualNetworkAdapter
oNetworkAdapter.DeviceId = Right(oWMIObj.Name, Len(oWMIObj.Name)-microsoftLength)
oNetworkAdapter.Name = oWMIObj.ElementName
set oNetworkAdapterList(instanceCount) = oNetworkAdapter
instanceCount = instanceCount + 1
' Get the Virtual Network data to which this Virtual Network is connected to
Dim oConnection, oConnectionList
Set oConnectionList = oWMIService.ExecQuery("SELECT Antecedent, Dependent FROM MSVM_ActiveConnection")
For Each oConnection in oConnectionList
' Antecedent of the connection is connected to the Virtual Network
' Dependent of the connection is connected to the Virtual Network Adapter
Dim dependent
dependent = Replace(oConnection.Dependent, "\\", "\")
If InStr(dependent, oWMIObj.Name) &gt; 0 Then
If InStr(oConnection.Antecedent, "Msvm_VirtualSwitch") &gt; 0 Then
Dim switchIndex
switchIndex = InStr(oConnection.Antecedent, "SystemName")
If switchIndex &gt; 0 Then
' Get Virtual Network object through the networkId
Dim networkId
networkId = Right(oConnection.Antecedent, Len(oConnection.Antecedent)-switchIndex-microsoftLength-1)
networkId = Left(networkId, Len(networkId)-1)
Dim oNetwork, oNetworkList
Set oNetworkList = oWMIService.ExecQuery("SELECT Name, ElementName FROM MSVM_VirtualSwitch WHERE Name='" &amp; networkId &amp; "'")
If (IsListEmpty(oNetworkList) = False) Then
Set oNetwork = oNetworkList.ItemIndex(0)
If IsObjectUnallocated(oNetwork) = False Then
' Add Virtual Network properties to the discovery class instance
oNetworkAdapter.ConnectedNetworkId = oNetwork.Name
oNetworkAdapter.ConnectedNetworkName = oNetwork.ElementName
Exit For
End If
End If
End If
End If
End If
Next
Next
End If
GetVirtualNetworkAdapters = oNetworkAdapterList
End Function


' Function to get all Virtual Drives
Function GetVirtualDrives(ByVal oVirtualMachine, ByRef oVHDService)
Dim oVSSD, oVSSDList, oVirtualDriveList(), driveCount
driveCount = 0

' Get Virtual System Setting Data associated with the virtual machine
Set oVSSDList = oVirtualMachine.Associators_("MSVM_SettingsDefineState", "MSVM_VirtualSystemSettingData")
If (IsListEmpty(oVSSDList) = False) Then
Set oVSSD = oVSSDList.ItemIndex(0)
If IsObjectUnallocated(oVSSD) = False Then
' Get a list of hardware associated with the virtual machine
Dim oRASDList, oRASD, oVirtualDrive
Set oRASDList = oVSSD.Associators_("MSVM_VirtualSystemSettingDataComponent", "MSVM_ResourceAllocationSettingData")
If IsListEmpty(oRASDList) = False Then
For Each oRASD in oRASDList
' Create discovery class instance based on hardware
Select Case oRASD.ResourceType
Case 22 'Hard Drive
Set oVirtualDrive = CreateHardDrive(oVirtualMachine, oRASD, oRASDList, oVHDService)
If IsObjectUnallocated(oVirtualDrive) = False Then
Redim Preserve oVirtualDriveList(driveCount+1)
Set oVirtualDriveList(driveCount) = oVirtualDrive
driveCount = driveCount + 1
End If
End Select
Next
End If
End If
End If
GetVirtualDrives = oVirtualDriveList
End Function


' Returns a Hard drive instance
Function CreateHardDrive(ByVal oVirtualMachine, ByVal oRASD, ByVal oRASDList, ByRef oVHDService)
Dim oVirtualDrive, oTemp, path, VHDType, i
VHDType = 0

' Create Virtual Drive instance
Set oVirtualDrive = new VirtualDrive
oVirtualDrive.DeviceId = oRASD.InstanceID
oVirtualDrive.Name = oRASD.ElementName &amp; " " &amp; oRASD.Address

' Find the associated image file of the Hard Drive
For i = 0 to (oRASDList.Count-1)
Set oTemp = oRASDList.ItemIndex(i)

If (oTemp.ResourceType = 5 Or oTemp.ResourceType = 6) And InStr(oRASD.Parent, Replace(oTemp.InstanceID, "\", "\\")) &gt; 0 Then
' Parent Controller (IDE=5, SCSI=6)
oVirtualDrive.ConnectedControllerName = oTemp.Caption
Elseif oTemp.ResourceType = 21 And InStr(oTemp.Parent, Replace(oRASD.InstanceID, "\", "\\")) &gt; 0 Then
' Set Image File path (Storage=21)
path = oTemp.Connection(0)
oVirtualDrive.ImageFile = path
' Set Drive type
If (IsObjectUnallocated(oVHDService) = False) Then
VHDType = GetHardDiskType(path, oVHDService)
End If
End If
Next

' Adding VHD type
If (VHDType = "") Then
VHDType = 0
End If
oVirtualDrive.DriveType = VHDType

Set CreateHardDrive = oVirtualDrive
End Function


' Function to get the Virtual Drive type
Function GetHardDiskType(ByVal path, ByRef oVHDService)
GetHardDiskType = "0"

Dim inParam, outParams
Set inParam = oVHDService.Methods_("GetVirtualHardDiskInfo").InParameters.SpawnInstance_()
If IsObjectUnallocated(inParam) = False Then
inParam.Path = path
Set outParams = oVHDService.ExecMethod_("GetVirtualHardDiskInfo", inParam)
If (IsObjectUnallocated(outParams) = False) Then
If (outParams.Info &gt; "") Then
' Parse Xml data to get Type
Dim xmlDoc, xPath, node
Set xmlDoc = MOMCreateObject("Microsoft.XMLDOM")
xmlDoc.async = "false"
xmlDoc.loadXML(outParams.Info)
xPath = "/INSTANCE/PROPERTY[@NAME='Type']/VALUE/child:text()"
Set node = xmlDoc.selectSingleNode(xPath)
If (IsObjectUnallocated(node) = False) Then
If (node.Text &gt; "") Then
GetHardDiskType = node.Text
End If
End If
End If
End If
End If
End Function



'Copyright (c) Microsoft Corporation. All rights reserved.

' Constants
Const SCOM_ERROR = 1
Const SCOM_WARNING = 2
Const SCOM_INFORMATION = 4

Const HKEY_LOCAL_MACHINE = &amp;H80000002

Dim SCRIPT_EVENT_ID

' Library Initializer
Sub InitializeCommon(iScriptEventID)
'set the script event id
SCRIPT_EVENT_ID = iScriptEventID
End Sub

' List class
Class List
Private m_aData
Private m_iCount
Private m_iCapacityIncrement

' Creates an empty list.
Private Sub Class_Initialize()
m_aData = Array(0)
m_iCount = 0
m_iCapacityIncrement = 10
End Sub

' Destroys the list.
Private Sub Class_Terminate()
'deallocate the array
Redim m_aData(0)
End Sub

' Getter for data (no range checking).
Public Property Get Data(iIndex)
If IsObject(m_aData(iIndex)) Then
Set Data = m_aData(iIndex)
Else
Data = m_aData(iIndex)
End if
End property

' Setter for data (no range checking).
Public Property Let Data(iIndex, vValue)
If IsObject(vValue) Then
Set m_aData(iIndex) = vValue
Else
m_aData(iIndex) = vValue
End if
End property

' Gets the whole array.
Public Property Get DataArray()
DataArray = m_aData
End property

' Gets the number of items currently stored in the list.
Public Property Get Count()
Count = m_iCount
End property

' Gets the current capacity of the list. (Adding beyond capacity will cause the list to be resized/reallocated.
Public Property Get Capacity()
Capacity = UBound(m_aData)
End property

' Gets number of items by which the array size will be increased when it needs to be reallocated.
Public Property Get CapacityIncrement()
CapacityIncrement = m_iCapacityIncrement
End property

' Sets the number of items by which the array will be lengThened when it
' needs reallocating. (No effect If value is less than 1.)
Public Property Let CapacityIncrement(iValue)
If iValue &gt; 0 Then
m_iCapacityIncrement = iValue
End if
End property

' Adds an item to the list. (List will be resized/reallocated as needed.)
public Function Add(vItem)
'do we have space?
If m_iCount &gt;= UBound(m_aData) Then
'no
'reallocate array
redim preserve m_aData(UBound(m_aData) + CapacityIncrement)
End if

'add it
Data(m_iCount) = vItem

'increment count
m_iCount = m_iCount + 1
End Function
End Class


' Check the list for null or empty
Function IsListEmpty(ByVal oList)
IsListEmpty = (IsNull(oList) = True) OR (oList.Count &lt; 1)
End Function


' Check object for null, empty or nothing
Function IsObjectUnallocated(ByVal obj)
IsObjectUnallocated = IsNull(obj) OR IsEmpty(obj) OR (TypeName(obj) = "Nothing")
End Function


' Get the Host Computer name
Function GetHostComputerName
Dim oNetwork
Set oNetwork = MOMCreateObject("WScript.Network")
GetHostComputerName = oNetwork.ComputerName
End Function


' Get the WMI object
Function GetWMIObject(ByVal namespace)
Dim oWMI

'get the object
On Error Resume Next
Set oWMI = GetObject(namespace)
If Err.Number &lt;&gt; 0 Or IsEmpty(oWMI) Then
ThrowScriptError "Unable to open WMI Namespace '" &amp; namespace &amp; "'. Check to see if the WMI service is enabled and running, and ensure this WMI namespace exists.", Err
End If
On Error Goto 0

Set GetWMIObject = oWMI
End Function


' Get Registry object
Function GetRegistryObject(ByVal computerName)
Set GetRegistryObject = GetWMIObject("winmgmts:\\" &amp; computerName &amp; "\root\default:StdRegProv")
End Function


' Creates an event and sends it back to the mom server without stopping the script.
Function ThrowScriptErrorNoAbort(ByVal message, ByVal oErr)
' Retrieve the name of this (running) script
Dim scriptFileName
scriptFileName = GetScriptName

If Not IsNull(oErr) Then
message = message &amp; " Cause: " &amp; oErr.Description
end if

On Error Resume Next
Dim oAPITemp
Set oAPITemp = CreateObject("MOM.ScriptAPI")
If Err.Number = 0 Then
oAPITemp.LogScriptEvent scriptFileName, SCRIPT_EVENT_ID, SCOM_ERROR, message
End If
On Error Goto 0
End Function


' Creates an error event, sends it back to the mom server, and stops the script.
Function ThrowScriptError(Byval message, ByVal oErr)
On Error Resume Next
ThrowScriptErrorNoAbort message, oErr
WScript.Quit
End Function


' Gets the script name
Function GetScriptName
Dim oFSO
Set oFSO = MOMCreateObject("Scripting.FileSystemObject")
GetScriptName = oFSO.GetFile(WScript.ScriptFullName).Name
set oFSO = nothing
End Function


' Creates an object
Function MOMCreateObject(ByVal name)
'create the object
On Error Resume Next
Set MOMCreateObject = CreateObject(name)
If Err.Number &lt;&gt; 0 Then
ThrowScriptError "Unable to create COM object '" &amp; name &amp; "'", Null
End If
On Error Goto 0
End Function

' Log the message
Sub Log(message, severity)
Dim oTempAPI, scriptName

'get script name
scriptName = GetScriptName

'create a temp mom api object
'(avoids having to pass the object every time or using a global)
Set oTempAPI = MOMCreateObject("MOM.ScriptAPI")

'log event
On Error Resume Next
Call oTempAPI.LogScriptEvent(scriptName, SCRIPT_EVENT_ID, severity, message)
On Error Goto 0
End Sub
</Script></ScriptBody>
<TimeoutSeconds>$Config/TimeoutSeconds$</TimeoutSeconds>
</ProbeAction>
<ConditionDetection ID="Filter" TypeID="System!System.ExpressionFilter">
<Expression>
<SimpleExpression>
<ValueExpression>
<XPathQuery Type="String">Property[@Name='Name']</XPathQuery>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value Type="String">$Target/Property[Type="Microsoft.Windows.HyperV.VirtualMachine"]/VirtualMachineId$</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
</ConditionDetection>
</MemberModules>
<Composition>
<Node ID="Filter">
<Node ID="Script">
<Node ID="Scheduler"/>
</Node>
</Node>
</Composition>
</Composite>
</ModuleImplementation>
<OutputType>System!System.PropertyBagData</OutputType>
</DataSourceModuleType>