﻿<ManagementPack ContentReadable="true" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <Manifest>
    <Identity>
      <ID>Microsoft.Windows.Cluster.VirtualServer.DiscoveryFix</ID>
      <Version>6.0.6277.0</Version>
    </Identity>
    <Name>Microsoft Windows Cluster Virtual Server Discovery Fix</Name>
    <References>
      <Reference Alias="Cluster">
        <ID>Microsoft.Windows.Cluster.Library</ID>
        <Version>6.0.6277.0</Version>
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
      <Reference Alias="Windows">
        <ID>Microsoft.Windows.Library</ID>
        <Version>6.0.5000.0</Version>
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
      <Reference Alias="System">
        <ID>System.Library</ID>
        <Version>6.0.5000.0</Version>
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
    </References>
  </Manifest>
  <TypeDefinitions>
    <ModuleTypes>
      <DataSourceModuleType ID="Microsoft.Windows.Cluster.VirtualServer.Discovery.DataSource" Accessibility="Public" RunAs="Cluster!Microsoft.Windows.Cluster.PrivilegedAccount" Batching="false">
        <Configuration>
          <xsd:element name="IntervalSeconds" type="xsd:integer" />
          <xsd:element name="SyncTime" type="xsd:string" />
        </Configuration>
        <OverrideableParameters>
          <OverrideableParameter ID="IntervalSeconds" Selector="$Config/IntervalSeconds$" ParameterType="int" />
          <OverrideableParameter ID="SyncTime" Selector="$Config/SyncTime$" ParameterType="string" />
        </OverrideableParameters>
        <ModuleImplementation Isolation="Any">
          <Composite>
            <MemberModules>
              <DataSource ID="DS" TypeID="System!System.Discovery.Scheduler">
                <Scheduler>
                  <SimpleReccuringSchedule>
                    <Interval>$Config/IntervalSeconds$</Interval>
                    <SyncTime>$Config/SyncTime$</SyncTime>
                  </SimpleReccuringSchedule>
                  <ExcludeDates />
                </Scheduler>
              </DataSource>
              <ProbeAction ID="Script" TypeID="Microsoft.Windows.Cluster.VirtualServer.Discovery.ScriptProbe" />
            </MemberModules>
            <Composition>
              <Node ID="Script">
                <Node ID="DS" />
              </Node>
            </Composition>
          </Composite>
        </ModuleImplementation>
        <OutputType>System!System.Discovery.Data</OutputType>
      </DataSourceModuleType>
      <ProbeActionModuleType ID="Microsoft.Windows.Cluster.VirtualServer.Discovery.ScriptProbe" Accessibility="Internal" RunAs="Cluster!Microsoft.Windows.Cluster.PrivilegedAccount" Batching="false" PassThrough="false">
        <Configuration />
        <ModuleImplementation Isolation="Any">
          <Composite>
            <MemberModules>
              <ProbeAction ID="Script" TypeID="Windows!Microsoft.Windows.ScriptDiscoveryProbe">
                <ScriptName>PopulateVirtualServerProperties.vbs</ScriptName>
                <Arguments>$MPElement$ $Target/Id$ $Target/Property[Type='Windows!Microsoft.Windows.Computer']/PrincipalName$</Arguments>
                <ScriptBody>
                  <![CDATA[
Option Explicit

Const wbemCimtypeUseDefault = 0   'Use Default Type CIM type - Custom
Const wbemCimtypeSint16     = 2   'Signed 16-bit integer 
Const wbemCimtypeSint32     = 3   'Signed 32-bit integer 
Const wbemCimtypeReal32     = 4   '32-bit real number 
Const wbemCimtypeReal64     = 5   '64-bit real number 
Const wbemCimtypeString     = 8   'String 
Const wbemCimtypeBoolean    = 11  'Boolean value 
Const wbemCimtypeObject     = 13  'CIM object 
Const wbemCimtypeSint8      = 16  'Signed 8-bit integer 
Const wbemCimtypeUint8      = 17  'Unsigned 8-bit integer 
Const wbemCimtypeUint16     = 18  'Unsigned 16-bit integer 
Const wbemCimtypeUint32     = 19  'Unsigned 32-bit integer 
Const wbemCimtypeSint64     = 20  'Signed 64-bit integer  
Const wbemCimtypeUint64     = 21  'Unsigned 64-bit integer 
Const wbemCimtypeDatetime   = 101 'Date/time value 
Const wbemCimtypeReference  = 102 'Reference to a CIM object 
Const wbemCimtypeChar16     = 103 '16-bit character 

Const ErrAction_None = 0
Const ErrAction_Trace = 1
Const ErrAction_ThrowError = 16
Const ErrAction_Abort = 32
Const ErrAction_ThrowErrorAndAbort = 48

Dim g_oUtil
Set g_oUtil = New Util

Call g_oUtil.SetDebugLevel(g_oUtil.DBG_NONE)

Dim oArgs
Set oArgs = WScript.Arguments

If oArgs.Count <> 3 Then
    g_oUtil.LogMessage _
            g_oUtil.DBG_ERROR, _
            "Need to provide arguments"

    Wscript.Quit -1
End If

'==========================================================================
' Initialize the arguments in VBScript
'==========================================================================

Dim SourceId, ManagedEntityId, FullyQualifiedName

SourceId = oArgs(0)
ManagedEntityId = oArgs(1)
FullyQualifiedName = oArgs(2)

g_oUtil.LogMessage _
        g_oUtil.DBG_TRACE, _
        "SourceId : " & SourceId  
g_oUtil.LogMessage _
        g_oUtil.DBG_TRACE, _
        "ManagedEntityId : " & ManagedEntityId  
g_oUtil.LogMessage _
        g_oUtil.DBG_TRACE, _
        "FullyQualifiedName : " & FullyQualifiedName  

'==========================================================================
' Main
'==========================================================================

Dim oAPI
Set oAPI = CreateObject("MOM.ScriptAPI")
If oAPI is Nothing Then
    g_oUtil.LogMessage _
            g_oUtil.DBG_ERROR, _
            "Failed to get Discovery API. MOM v3 must be installed to execute this script"

    if 0 <> Err.number then
        g_oUtil.LogMessage _
                g_oUtil.DBG_ERROR, _
                "Failed with error " & Err.number & " - " & Err.Description
    end if
End If

Call DiscoverInstances()

'==========================================================================
' FUNCTIONS
'==========================================================================

Sub ThrowEmptyDiscoveryData()
    Dim oDiscoveryDataTmp
    set oDiscoveryDataTmp = oAPI.CreateDiscoveryData(0, SourceId, ManagedEntityId)
    Call oAPI.Return(oDiscoveryDataTmp)
End Sub

Sub DiscoverInstances()

    g_oUtil.LogMessage _
            g_oUtil.DBG_TRACE, _
            "Started dicovery at machine local time: " & CStr(Time) 

    Dim oDiscoveryData
    Set oDiscoveryData = oAPI.CreateDiscoveryData ( _
            0, _
            SourceId, _
            ManagedEntityId _
        )

    If oDiscoveryData is Nothing Then
        g_oUtil.LogMessage _
                g_oUtil.DBG_ERROR, _
                "Failed to get Discovery Data Object. MOM v3 must be installed to execute this script"

        if 0 <> Err.number then
            g_oUtil.LogMessage _
                    g_oUtil.DBG_ERROR, _
                    "Failed with error " & Err.number & " - " & Err.Description
        end if

        Exit Sub
    End If

    Call Discover ( oDiscoveryData )
    Call oAPI.Return(oDiscoveryData)

    g_oUtil.LogMessageNewLine _
            g_oUtil.DBG_TRACE, _
            "Finished dicovery at machine local time: " & CStr(Time) 

End Sub

'==========================================================================
' Populate VirtualServer
'==========================================================================
Public Sub Discover( _
        ByRef oDiscoveryData _
    )

    Dim DNSName

    Dim oInstance
    Set oInstance = oDiscoveryData.CreateClassInstance( _
            "$MPElement[Name='Cluster!Microsoft.Windows.Cluster.VirtualServer']$" _
        )

    With oInstance
        .AddProperty _
                "$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", _
                FullyQualifiedName

        .AddProperty _
              "$MPElement[Name='Windows!Microsoft.Windows.Computer']/DNSName$", _
              FullyQualifiedName
    End With

    Call oDiscoveryData.AddInstance(oInstance)

End Sub

'==========================================================================
' Class:        Util
' Description:  Utility methods for logging
'==========================================================================
Class Util

    ' Used to say to LogMessage when/how to print the message.
    Public DBG_NONE
    Public DBG_ERROR 
    Public DBG_WARNING 
    Public DBG_TRACE

    'Internal Debug Level
    Private m_nDebugLevel   

    '======================================================================
    ' Method:       Class_Initialize
    ' Description:  This is the constructor 
    ' Parameters:
    '======================================================================
    Private Sub Class_Initialize()
        ' Initialize Debug level constants
        DBG_TRACE = 1
        DBG_WARNING = 2
        DBG_ERROR = 3
        DBG_NONE = 4

        'by default only errors are logged
        m_nDebugLevel = DBG_ERROR
        
    End Sub

    '======================================================================
    ' Method:       GetCurrentLevel
    ' Description:  retrieve current logging level.
    ' Parameters:
    '======================================================================
    Public Function GetCurrentLevel()
            GetCurrentLevel = m_nDebugLevel
    End Function

    '======================================================================
    ' Method:       SetDebugLevel
    ' Description:  To change the debugging output level of information 
    '               generated by this utility.
    ' Parameters:
    '               nLevel - DBG_NONE, DBG_TRACE, DBG_WARNING or DBG_ERROR
    '======================================================================
    Public Sub SetDebugLevel(ByVal nLevel)
            m_nDebugLevel = nLevel
    End Sub

    '======================================================================
    ' Method:       LogMessage
    ' Description:  Log a debug message to ScriptContext
    ' Parameters:
    '               nLevel      - Debug level for the message that
    '                             we're logging. 
    '               strMessage  - The message to write to the trace.
    '======================================================================
    Public Sub LogMessage( _
            ByVal nLevel, _
            ByVal strMessage _
        )
        If (nLevel >= GetCurrentLevel()) Then
            if (nLevel = DBG_ERROR) Then
                WScript.Echo "[Error]: " & strMessage
            ElseIf (nLevel = DBG_WARNING) Then
                WScript.Echo "[Warning]: " & strMessage
            ElseIf (nLevel = DBG_TRACE) Then
                WScript.Echo "[Trace]: " & strMessage
            End If
        End If
    End Sub
    Public Sub LogMessageNewLine( _
            ByVal nLevel, _
            ByVal strMessage _
        )
        If (nLevel >= GetCurrentLevel()) Then
            if (nLevel = DBG_ERROR) Then
                WScript.Echo vbCrLf & "[Error]: " & strMessage
            ElseIf (nLevel = DBG_WARNING) Then
                WScript.Echo vbCrLf & "[Warning]: " & strMessage
            ElseIf (nLevel = DBG_TRACE) Then
                WScript.Echo vbCrLf & "[Trace]: " & strMessage
            End If
        End If
    End Sub

End Class ' Util
]]>
                </ScriptBody>
                <TimeoutSeconds>300</TimeoutSeconds>
              </ProbeAction>
            </MemberModules>
            <Composition>
              <Node ID="Script" />
            </Composition>
          </Composite>
        </ModuleImplementation>
        <OutputType>System!System.Discovery.Data</OutputType>
        <InputType>System!System.BaseData</InputType>
      </ProbeActionModuleType>
    </ModuleTypes>
  </TypeDefinitions>
  <Monitoring>
    <Discoveries>
      <Discovery ID="Microsoft.Windows.Cluster.VirtualServer.Discovery" Enabled="true" Target="Cluster!Microsoft.Windows.Cluster.VirtualServer" ConfirmDelivery="false" Remotable="true" Priority="Normal">
        <Category>Discovery</Category>
        <DiscoveryTypes>
          <DiscoveryClass TypeID="Cluster!Microsoft.Windows.Cluster.VirtualServer" />
        </DiscoveryTypes>
        <DataSource ID="DiscoveryDataSource" TypeID="Microsoft.Windows.Cluster.VirtualServer.Discovery.DataSource">
          <IntervalSeconds>85</IntervalSeconds>
          <SyncTime />
        </DataSource>
      </Discovery>
    </Discoveries>
  </Monitoring>
  <LanguagePacks>
    <LanguagePack ID="ENU" IsDefault="true">
      <DisplayStrings>
        <DisplayString ElementID="Microsoft.Windows.Cluster.VirtualServer.Discovery">
          <Name>Cluster Virtual Server Discovery</Name>
          <Description>This rule uses populates Virtual Server instance with missing properties.</Description>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.Cluster.VirtualServer.Discovery.DataSource">
          <Name>Virtual Server Discovery population</Name>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.Cluster.VirtualServer.Discovery.DataSource" SubElementID="IntervalSeconds">
          <Name>Interval Seconds</Name>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.Cluster.VirtualServer.Discovery.DataSource" SubElementID="SyncTime">
          <Name>Synchronization Time</Name>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.Cluster.VirtualServer.Discovery.ScriptProbe">
          <Name>Virtual Server Discovery population script</Name>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.Cluster.VirtualServer.DiscoveryFix">
          <Name>Windows Cluster Virtual Server Discovery Fix</Name>
          <Description>Microsoft Windows Cluster Virtual Server Discovery Fix: This management pack contains the rule that populates instance of Virtual Server entity with values for missing properties.</Description>
        </DisplayString>
      </DisplayStrings>
      <KnowledgeArticles>
        <KnowledgeArticle ElementID="Microsoft.Windows.Cluster.VirtualServer.Discovery" Visible="true">
          <MamlContent>
            <maml:section xmlns:maml="http://schemas.microsoft.com/maml/2004/10">
              <maml:title>Summary</maml:title>
              <maml:para>This discovery rule populates instances of the virtual server.</maml:para>
            </maml:section>
          </MamlContent>
        </KnowledgeArticle>
      </KnowledgeArticles>
    </LanguagePack>
  </LanguagePacks>
</ManagementPack>
