<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.KeyManagementService</ID>
      <Version>6.0.7234.0</Version>
    </Identity>
    <Name>This management pack monitors Microsoft Key Management Service</Name>
    <References>
      <Reference Alias="SC">
        <ID>Microsoft.SystemCenter.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>
      <Reference Alias="Windows">
        <ID>Microsoft.Windows.Library</ID>
        <Version>6.0.5000.0</Version>
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
      <Reference Alias="Health">
        <ID>System.Health.Library</ID>
        <Version>6.0.5000.0</Version>
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
      <Reference Alias="Performance">
        <ID>System.Performance.Library</ID>
        <Version>6.0.5000.0</Version>
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
    </References>
  </Manifest>
  <TypeDefinitions>
    <EntityTypes>
      <ClassTypes>
        <ClassType ID="Microsoft.Windows.KeyManagement.Service" Accessibility="Public" Abstract="false" Base="Windows!Microsoft.Windows.ComputerRole" Hosted="true" Singleton="false">
          <Property ID="ProcessID" Type="int" Key="false" CaseSensitive="false" Length="256" MinLength="0" />
          <Property ID="ImageName" Type="string" Key="true" CaseSensitive="false" Length="256" MinLength="1" />
          <Property ID="FilePath" Type="string" Key="false" CaseSensitive="false" Length="256" MinLength="0" />
          <Property ID="ServiceName" Type="string" Key="false" CaseSensitive="false" Length="256" MinLength="0" />
          <Property ID="ServiceState" Type="string" Key="false" CaseSensitive="false" Length="256" MinLength="0" />
          <Property ID="KMSServiceVersion" Type="string" Key="false" CaseSensitive="false" Length="256" MinLength="0" />
          <Property ID="KMSServicePath" Type="string" Key="false" CaseSensitive="false" Length="256" MinLength="1" />
        </ClassType>
        <ClassType ID="Microsoft.Windows.KeyManagement.Product" Accessibility="Public" Abstract="false" Base="Windows!Microsoft.Windows.ApplicationComponent" Hosted="true" Singleton="false">
          <Property ID="ProductSkuId" Type="string" Key="true" CaseSensitive="false" Length="256" MinLength="0" />
          <Property ID="ProductSkuName" Type="string" Key="false" CaseSensitive="false" Length="256" MinLength="1" />
          <Property ID="ProductSkuDescription" Type="string" Key="false" CaseSensitive="false" Length="256" MinLength="0" />
          <Property ID="KMSCurrentCount" Type="int" Key="false" CaseSensitive="false" Length="256" MinLength="0" />
          <Property ID="LastActivity" Type="string" Key="false" CaseSensitive="false" Length="256" MinLength="0" />
          <Property ID="LastActivityYear" Type="string" Key="false" CaseSensitive="false" Length="256" MinLength="0" />
          <Property ID="LastActivityMonth" Type="string" Key="false" CaseSensitive="false" Length="256" MinLength="0" />
          <Property ID="LastActivityDay" Type="string" Key="false" CaseSensitive="false" Length="256" MinLength="0" />
          <Property ID="LastActivityHour" Type="string" Key="false" CaseSensitive="false" Length="256" MinLength="0" />
          <Property ID="LastActivityMinute" Type="string" Key="false" CaseSensitive="false" Length="256" MinLength="0" />
          <Property ID="TotalRequests" Type="int" Key="false" CaseSensitive="false" Length="256" MinLength="0" />
          <Property ID="IdleMinutes" Type="string" Key="false" CaseSensitive="false" Length="256" MinLength="0" />
        </ClassType>
        <ClassType ID="Microsoft.Windows.KeyManagement.ComputerGroup" Abstract="false" Accessibility="Public" Base="SC!Microsoft.SystemCenter.ComputerGroup" Hosted="false" Singleton="true" />
      </ClassTypes>
      <RelationshipTypes>
        <RelationshipType ID="Microsoft.Windows.KeyManagement.ServiceHostsProduct" Accessibility="Public" Abstract="false" Base="System!System.Hosting">
          <Source>Microsoft.Windows.KeyManagement.Service</Source>
          <Target>Microsoft.Windows.KeyManagement.Product</Target>
        </RelationshipType>
      </RelationshipTypes>
    </EntityTypes>
    <ModuleTypes>
      <DataSourceModuleType ID="Microsoft.Windows.KeyManagement.Service.Discovery.DataSource" Accessibility="Public" Batching="false">
        <Configuration>
          <xsd:element name="IntervalSeconds" type="xsd:integer" />
          <xsd:element name="SyncTime" type="xsd:string" />
          <xsd:element name="ComputerID" type="xsd:string" />
          <xsd:element name="ComputerName" type="xsd:string" />
          <xsd:element name="TimeoutSeconds" type="xsd:int" />
        </Configuration>
        <OverrideableParameters>
          <OverrideableParameter ID="IntervalSeconds" Selector="$Config/IntervalSeconds$" ParameterType="int" />
          <OverrideableParameter ID="SyncTime" Selector="$Config/SyncTime$" ParameterType="string" />
          <OverrideableParameter ID="TimeoutSeconds" Selector="$Config/TimeoutSeconds$" ParameterType="int" />
        </OverrideableParameters>
        <ModuleImplementation Isolation="Any">
          <Composite>
            <MemberModules>
              <DataSource ID="DS" TypeID="Windows!Microsoft.Windows.TimedScript.DiscoveryProvider">
                <IntervalSeconds>$Config/IntervalSeconds$</IntervalSeconds>
                <SyncTime>$Config/SyncTime$</SyncTime>
                <ScriptName>KMSDiscovery.vbs</ScriptName>
                <Arguments>$MPElement$ $Target/Id$ $Config/ComputerID$ $Config/ComputerName$"</Arguments>
                <ScriptBody>

' Copyright (c) Microsoft Corporation. All rights reserved.
' Arguments:
'  0 - TargetComputer
'  1 - TargetComputerID
'  2 - SourceID
'  3 - ManagedEntityID
'
' This scripts discovers instances of the KMS Service class.
'
' The script detects the presence of KMS functionality on a given machine by examining 
' the registry keys value "KeyManagementServiceVersion" under "SOFTWARE\Microsoft\Windows NT\CurrentVersion\SL"
' or "SOFTWARE\Microsoft\Windows NT\CurrentVersion\SoftwareProtectionPlatform".
'
' After the script determines that KMS functionaity is enabled it will use a WQL query to extract
' information from the WMI class Win32_Service (searching for services named 'sppsvc' or 'slsvc'.)
'
' Finally an instance of the KMS Service class is created using information from the WMI object and registry contents.
'
Option Explicit

Dim TargetComputer
Dim TargetComputerID
Dim SourceID
Dim ManagedEntityID

' it suppresses ThrowScriptErrorNoAbort only once. I need it for reading registry when registry key is not present
' and this is no error condition. 
Dim g_bSuppressThrowScriptErrorNoAbort

Call Main()
'******************************************************************************
Class Registry
  Public HKEY_CLASSES_ROOT
  Public HKEY_CURRENT_USER
  Public HKEY_LOCAL_MACHINE
  Public HKEY_USERS
  Public HKEY_CURRENT_CONFIG
  Public HKEY_DYN_DATA 

  Public ERROR_ACCESS_DENIED
  Public ERROR_KEY_NOT_FOUND
  Public ERROR_VALUE_NOT_FOUND
  Public SUCCESS
  
  Private m_oReg
  Private m_lHive
  
  Private Sub Class_Initialize()
      HKEY_CLASSES_ROOT = &amp;H80000000
      HKEY_CURRENT_USER = &amp;H80000001 
      HKEY_LOCAL_MACHINE = &amp;H80000002
      HKEY_USERS = &amp;H80000003 
      HKEY_CURRENT_CONFIG = &amp;H80000005
      HKEY_DYN_DATA = &amp;H80000006
      
      ERROR_ACCESS_DENIED = 5
      ERROR_KEY_NOT_FOUND = 2
      ERROR_VALUE_NOT_FOUND = 1
      SUCCESS = 0
      
      m_lHive = HKEY_LOCAL_MACHINE
  End Sub
  
  Public Sub Connect(ByVal sHostName)
      Set m_oReg = GetObject("winmgmts://" &amp; sHostName &amp; "/root/default:StdRegProv")
  End Sub
  
  Public Property Get Hive()
      Hive = m_lHive
  End Property
  
  Public Property Let Hive(ByVal lHive)
      m_lHive = lHive
  End Property
  
  Public Function ReadDWORDValue(ByVal sKeyPath, ByVal sValueName, ByRef lResult)
      Dim lValue
      lResult = m_oReg.GetDWORDValue(m_lHive, sKeyPath, sValueName, lValue)
      ReadDWORDValue = lValue
  End Function
  
  Public Function ReadStringValue(ByVal sKeyPath, ByVal sValueName, ByRef lResult)
      Dim sValue
      lResult = m_oReg.GetStringValue(m_lHive, sKeyPath, sValueName, sValue)
      ReadStringValue = sValue
  End Function
  
  Public Function ReadMultiStringValue(ByVal sKeyPath, ByVal sValueName, ByRef lResult)
      Dim aValues
      lResult = m_oReg.GetMultiStringValue(m_lHive, sKeyPath, sValueName, aValues)
      ReadMultiStringValue = aValues
  End Function
  
  Public Function EnumKeys(ByVal sKeyPath, ByRef lResult)
      Dim aSubKeys
      lResult = m_oReg.EnumKey(m_lHive, sKeyPath, aSubKeys)
      EnumKeys = aSubKeys
  End Function
  
  Public Function CreateKey(ByVal sKeyPath)
      CreateKey = m_oReg.CreateKey(m_lHive, sKeyPath)
  End Function
  
  Public Function WriteStringValue(ByVal sKeyPath, ByVal sValueName, ByVal sValue)
      WriteStringValue = m_oReg.SetStringValue(m_lHive, sKeyPath, sValueName, sValue)
  End Function
  
  Public Function DeleteValue(ByVal sKeyPath, ByVal sValueName)
      DeleteValue = m_oReg.DeleteValue(m_lHive, sKeyPath, sValueName)
  End Function
  
  Public Function ReadBinaryValue(ByVal sKeyPath, ByVal sValueName, ByRef lResult)
      Dim aData
      lResult = m_oReg.GetBinaryValue(m_lHive, sKeyPath, sValueName, aData)
      ReadBinaryValue = aData
  End Function
End Class
'******************************************************************************
Class SafeRegistry
  Private m_oError
  Private m_oRegistry
  Private m_sHive
  Private m_lSuppressionFlags
  Private m_sHost
  
  Public SUPPRESS_KEY_NOT_FOUND
  Public SUPPRESS_VALUE_NOT_FOUND
  Public SUPPRESS_ACCESS_DENIED
  Public SUPPRESS_ALL
  
  Public HKEY_CLASSES_ROOT
  Public HKEY_CURRENT_USER
  Public HKEY_LOCAL_MACHINE
  Public HKEY_USERS
  Public HKEY_CURRENT_CONFIG
  Public HKEY_DYN_DATA 

  Public ERROR_ACCESS_DENIED
  Public ERROR_KEY_NOT_FOUND
  Public ERROR_VALUE_NOT_FOUND
  Public SUCCESS
  
  Private DEFAULT_VALUE_NAME
  
  Private Sub Class_Initialize()
      Set m_oError = New Error
      Set m_oRegistry = New Registry
      
      SUPPRESS_KEY_NOT_FOUND = &amp;H00000001
      SUPPRESS_VALUE_NOT_FOUND = &amp;H00000002
      SUPPRESS_ACCESS_DENIED = &amp;H00000004
      SUPPRESS_ALL = &amp;HFFFFFFFF
      
      HKEY_CLASSES_ROOT = m_oRegistry.HKEY_CLASSES_ROOT
      HKEY_CURRENT_USER = m_oRegistry.HKEY_CURRENT_USER
      HKEY_LOCAL_MACHINE = m_oRegistry.HKEY_LOCAL_MACHINE
      HKEY_USERS = m_oRegistry.HKEY_USERS
      HKEY_CURRENT_CONFIG = m_oRegistry.HKEY_CURRENT_CONFIG
      HKEY_DYN_DATA  = m_oRegistry.HKEY_DYN_DATA

      ERROR_ACCESS_DENIED = m_oRegistry.ERROR_ACCESS_DENIED
      ERROR_KEY_NOT_FOUND = m_oRegistry.ERROR_KEY_NOT_FOUND
      ERROR_VALUE_NOT_FOUND = m_oRegistry.ERROR_VALUE_NOT_FOUND
      SUCCESS = m_oRegistry.SUCCESS
      
      DEFAULT_VALUE_NAME = "(Default)"
      
      m_lSuppressionFlags = 0
      Hive = HKEY_LOCAL_MACHINE
  End Sub
  
  Public Function Connect(ByVal sHostName)
      Connect = False
      m_sHost = sHostName
      On Error Resume Next
      m_oRegistry.Connect sHostName
      m_oError.Save
      On Error Goto 0
      
      If m_oError.Number &lt;&gt; 0 Then 
          ThrowScriptErrorNoAbort "Failed to connect to the WMI registry provider on " &amp; sHostName , m_oError
      Else
          Connect = True
      End If
  End Function
  
  Public Property Get Hive()
      Hive = m_oRegistry.Hive
  End Property
  
  Public Property Let Hive(ByVal lHive)
      Select Case lHive
          Case HKEY_CLASSES_ROOT
              m_sHive = "HKCR"
          Case HKEY_CURRENT_USER
              m_sHive = "HKCU"
          Case HKEY_LOCAL_MACHINE
              m_sHive = "HKLM"
          Case HKEY_USERS
              m_sHive = "HKU"
          Case HKEY_CURRENT_CONFIG
              m_sHive = "HKCC"
          Case HKEY_DYN_DATA
              m_sHive = "HKDD"
          Case Else
              m_sHive = "Invalid"
      End Select
      m_oRegistry.Hive = lHive
  End Property
  
  Public Property Let SuppressionFlags(ByVal lValue)
      m_lSuppressionFlags = lValue
  End Property
  
  Public Property Get SuppressionFlags()
      SuppressionFlags = m_lSuppressionFlags
  End Property
  
  Public Function ReadDWORDValue(ByVal sKeyPath, ByVal sValueName, ByRef lResult)
      ReadDWORDValue = Null
      
      On Error Resume Next
      ReadDWORDValue = m_oRegistry.ReadDWORDValue(sKeyPath, sValueName, lResult)
      m_oError.Save
      On Error Goto 0
      
      If m_oError.Number &lt;&gt; 0 Then 
          ThrowScriptErrorNoAbort GET_ERROR_READING_REGISTRY_MESSAGE(m_sHost, m_sHive, sKeyPath, sValueName), m_oError
          Exit Function
      End If
      
      HandleResult m_sHost, m_sHive, sKeyPath, sValueName, lResult
  End Function
  
  Public Function ReadStringValue(ByVal sKeyPath, ByVal sValueName, ByRef lResult)
      ReadStringValue = Null
      
      On Error Resume Next
      ReadStringValue = m_oRegistry.ReadStringValue(sKeyPath, sValueName, lResult)
      m_oError.Save
      On Error Goto 0
      
      If m_oError.Number &lt;&gt; 0 Then
          ThrowScriptErrorNoAbort GET_ERROR_READING_REGISTRY_MESSAGE(m_sHost, m_sHive, sKeyPath, sValueName), m_oError
          Exit Function
      End If

      HandleResult m_sHost, m_sHive, sKeyPath, sValueName, lResult
  End Function

  Public Function ReadMultiStringValue(ByVal sKeyPath, ByVal sValueName, ByRef lResult)
      ReadMultiStringValue = Null
      
      On Error Resume Next
      ReadMultiStringValue = m_oRegistry.ReadMultiStringValue(sKeyPath, sValueName, lResult)
      m_oError.Save
      On Error Goto 0
      
      If m_oError.Number &lt;&gt; 0 Then
          ThrowScriptErrorNoAbort GET_ERROR_READING_REGISTRY_MESSAGE(m_sHost, m_sHive, sKeyPath, sValueName), m_oError
          Exit Function
      End If

      HandleResult m_sHost, m_sHive, sKeyPath, sValueName, lResult
  End Function
  
  Public Function EnumKeys(ByVal sKeyPath, ByRef lResult)
      EnumKeys = Null
      
      On Error Resume Next
      EnumKeys = m_oRegistry.EnumKeys(sKeyPath, lResult)
      m_oError.Save
      On Error Goto 0
      
      If m_oError.Number &lt;&gt; 0 Then
          ThrowScriptErrorNoAbort GET_ERROR_READING_KEY_MESSAGE(m_sHost, m_sHive, sKeyPath), m_oError
          Exit Function
      End If
      
      HandleResult m_sHost, m_sHive, sKeyPath, "", lResult
  End Function
  
  Public Function CreateKey(ByVal sKeyPath)
      Dim lResult
      On Error Resume next
      lResult = m_oRegistry.CreateKey(sKeyPath)
      m_oError.Save
      On Error Goto 0
      
      If m_oError.Number &lt;&gt; 0 Then
          ThrowScriptErrorNoAbort GET_ERROR_CREATING_KEY_MESSAGE(m_sHost, m_sHive, sKeyPath), m_oError
          Exit Function
      End If
      
      HandleResult m_sHost, m_sHive, sKeyPath, "", lResult
      CreateKey = lResult
  End Function
  
  Public Function WriteStringValue(ByVal sKeyPath, ByVal sValueName, ByVal sValue)
      Dim lResult
      On Error Resume Next
      lResult = m_oRegistry.WriteStringValue(sKeyPath, sValueName, sValue)
      m_oError.Save
      On Error Goto 0
      
      If m_oError.Number &lt;&gt; 0 Then
          ThrowScriptErrorNoAbort GET_ERROR_WRITING_REGISTRY_MESSAGE(m_sHost, m_sHive, sKeyPath, sValueName), m_oError
          Exit Function
      End If
      
      HandleResult m_sHost, m_sHive, sKeyPath, sValueName, lResult
      WriteStringValue = lResult
  End Function
  
  Public Function DeleteValue(ByVal sKeyPath, ByVal sValueName)
      Dim lResult
      On Error Resume Next
      lResult = m_oRegistry.DeleteValue(sKeyPath, sValueName)
      m_oError.Save
      On Error Goto 0
      
      If m_oError.Number &lt;&gt; 0 Then
          ThrowScriptErrorNoAbort GET_ERROR_DELETING_VALUE_MESSAGE(m_sHost, m_sHive, sKeyPath, sValueName), m_oError
          Exit Function
      End If
      
      '#doc
      'This method seems to return key not found even if it is the value that is not found.
      '#end doc
      If lResult = ERROR_KEY_NOT_FOUND Then lResult = ERROR_VALUE_NOT_FOUND
      HandleResult m_sHost, m_sHive, sKeyPath, sValueName, lResult
      DeleteValue = lResult
  End Function
  
  Public Function ReadBinaryValue(ByVal sKeyPath, ByVal sValueName, ByRef lResult)
      ReadBinaryValue = Null
      
      On Error Resume Next
      ReadBinaryValue = m_oRegistry.ReadBinaryValue(sKeyPath, sValueName, lResult)
      m_oError.Save
      On Error Goto 0
      
      If m_oError.Number &lt;&gt; 0 Then
          ThrowScriptErrorNoAbort GET_ERROR_READING_REGISTRY_MESSAGE(m_sHost, m_sHive, sKeyPath, sValueName), m_oError
          Exit Function
      End If

      HandleResult m_sHost, m_sHive, sKeyPath, sValueName, lResult    
  End Function
  
  Private Sub HandleResult(ByVal sHost, ByVal sHive, ByVal sKeyPath, ByVal sValueName, ByVal lResult)
      Select Case lResult
          Case SUCCESS 
              Exit Sub
          Case ERROR_ACCESS_DENIED
              If (SuppressionFlags And SUPPRESS_ACCESS_DENIED) = 0 Then
                  ThrowScriptErrorNoAbort GET_REGISTRY_ACCESS_DENIED_MESSAGE(sHost, sHive, sKeyPath, sValueName), Err
              Else
                  Wscript.Echo GET_REGISTRY_ACCESS_DENIED_MESSAGE(sHost, sHive, sKeyPath, sValueName)
              End If
          Case ERROR_VALUE_NOT_FOUND
              If (SuppressionFlags And SUPPRESS_VALUE_NOT_FOUND) = 0 Then
                  ThrowScriptErrorNoAbort GET_REGISTRY_VALUE_NOT_FOUND_MESSAGE(sHost, sHive, sKeyPath, sValueName), Err
              Else
                  Wscript.Echo GET_REGISTRY_VALUE_NOT_FOUND_MESSAGE(sHost, sHive, sKeyPath, sValueName)
              End If
          Case ERROR_KEY_NOT_FOUND
              If (SuppressionFlags And SUPPRESS_KEY_NOT_FOUND) = 0 Then
                  ThrowScriptErrorNoAbort GET_REGISTRY_KEY_NOT_FOUND_MESSAGE(sHost, sHive, sKeyPath), Err
              Else
                  Wscript.Echo GET_REGISTRY_KEY_NOT_FOUND_MESSAGE(sHost, sHive, sKeyPath)
              End If
          Case Else
              If (SuppressionFlags And SUPPRESS_ALL) = 0 Then
                  ThrowScriptErrorNoAbort GET_ERROR_READING_REGISTRY_MESSAGE(sHost, sHive, sKeyPath, sValueName), Err
              Else
                  Wscript.Echo GET_ERROR_READING_REGISTRY_MESSAGE(sHost, sHive, sKeyPath, sValueName)
              End If
      End Select
  End Sub
  
  Private Function GET_REGISTRY_ACCESS_DENIED_MESSAGE(ByVal sHost, ByVal sHive, ByVal sRegKey, ByVal sRegValue)
      Const REGISTRY_ACCESS_DENIED_MESSAGE = "Access denied while reading registry value [\\{Host}\{Hive}\{RegKey}\{RegValue}]"
      If sRegValue = "" Then sRegValue = DEFAULT_VALUE_NAME
      Dim sResult
      sResult = Replace(REGISTRY_ACCESS_DENIED_MESSAGE, "{RegKey}", sRegKey)
      sResult = Replace(sResult, "{Hive}", sHive)
      sResult = Replace(sResult, "{Host}", sHost)
      GET_REGISTRY_ACCESS_DENIED_MESSAGE = Replace(sResult, "{RegValue}", sRegValue)
  End Function

  Private Function GET_REGISTRY_VALUE_NOT_FOUND_MESSAGE(ByVal sHost, ByVal sHive, ByVal sRegKey, ByVal sRegValue)
      Const REGISTRY_VALUE_NOT_FOUND_MESSAGE = "Registry value [\\{Host}\{Hive}\{RegKey}\{RegValue}] not found"
      If sRegValue = "" Then sRegValue = DEFAULT_VALUE_NAME
      Dim sResult
      sResult = Replace(REGISTRY_VALUE_NOT_FOUND_MESSAGE, "{RegKey}", sRegKey)
      sResult = Replace(sResult, "{Hive}", sHive)
      sResult = Replace(sResult, "{Host}", sHost)
      GET_REGISTRY_VALUE_NOT_FOUND_MESSAGE = Replace(sResult, "{RegValue}", sRegValue)
  End Function

  Private Function GET_ERROR_READING_REGISTRY_MESSAGE(ByVal sHost, ByVal sHive, ByVal sRegKey, ByVal sRegValue)
      Const ERROR_READING_REGISTRY_MESSAGE = "Error while reading registry value [\\{Host}\{Hive}\{RegKey}\{RegValue}]"
      If sRegValue = "" Then sRegValue = DEFAULT_VALUE_NAME
      Dim sResult
      sResult = Replace(ERROR_READING_REGISTRY_MESSAGE, "{RegKey}", sRegKey)        
      sResult = Replace(sResult, "{Hive}", sHive)
      sResult = Replace(sResult, "{Host}", sHost)
     GET_ERROR_READING_REGISTRY_MESSAGE = Replace(sResult, "{RegValue}", sRegValue)
  End Function

  Private Function GET_REGISTRY_KEY_NOT_FOUND_MESSAGE(ByVal sHost, ByVal sHive, ByVal sRegKey)
      Const REGISTRY_KEY_NOT_FOUND_MESSAGE = "Registry key [\\{Host}\{Hive}\{RegKey}] not found"
      Dim sResult
      sResult = Replace(REGISTRY_KEY_NOT_FOUND_MESSAGE, "{Hive}", sHive)
      sResult = Replace(sResult, "{Host}", sHost)
      GET_REGISTRY_KEY_NOT_FOUND_MESSAGE = Replace(sResult, "{RegKey}", sRegKey)
  End Function

  Private Function GET_ERROR_READING_KEY_MESSAGE(ByVal sHost, ByVal sHive, ByVal sRegKey)
      Const ERROR_READING_KEY_MESSAGE = "Error while reading registry key [\\{Host}\{Hive}\{RegKey}]"
      Dim sResult
      sResult = Replace(ERROR_READING_KEY_MESSAGE, "{Hive}", sHive)
      sResult = Replace(sResult, "{Host}", sHost)
      GET_ERROR_READING_KEY_MESSAGE = Replace(sResult, "{RegKey}", sRegKey)
  End Function
  
  Private Function GET_ERROR_CREATING_KEY_MESSAGE(ByVal sHost, ByVal sHive, ByVal sRegKey)
      Const ERROR_CREATING_KEY_MESSAGE = "Error while creating registry key [\\{Host}\{Hive}\{RegKey}]"
      Dim sResult
      sResult = Replace(ERROR_CREATING_KEY_MESSAGE, "{Hive}", sHive)
      sResult = Replace(sResult, "{Host}", sHost)
      GET_ERROR_CREATING_KEY_MESSAGE = Replace(sResult, "{RegKey}", sRegKey)
  End Function
  
  Private Function GET_ERROR_WRITING_REGISTRY_MESSAGE(ByVal sHost, ByVal sHive, ByVal sRegKey, ByVal sRegValue)
      Const ERROR_WRITING_REGISTRY_MESSAGE = "Error while writing registry value [\\{Host}\{Hive}\{RegKey}\{RegValue}]"
      If sRegValue = "" Then sRegValue = DEFAULT_VALUE_NAME
      Dim sResult
      sResult = Replace(ERROR_WRITING_REGISTRY_MESSAGE, "{RegKey}", sRegKey)        
      sResult = Replace(sResult, "{Hive}", sHive)
      sResult = Replace(sResult, "{Host}", sHost)
      GET_ERROR_WRITING_REGISTRY_MESSAGE = Replace(sResult, "{RegValue}", sRegValue)
  End Function
  
  Private Function GET_ERROR_DELETING_VALUE_MESSAGE(ByVal sHost, ByVal sHive, ByVal sRegKey, ByVal sRegValue)
      Const ERROR_DELETING_VALUE_MESSAGE = "Error while deleting registry value [\\{Host}\{Hive}\{RegKey}\{RegValue}]"
      If sRegValue = "" Then sRegValue = DEFAULT_VALUE_NAME
      Dim sResult
      sResult = Replace(ERROR_DELETING_VALUE_MESSAGE, "{RegKey}", sRegKey)        
      sResult = Replace(sResult, "{Hive}", sHive)
      sResult = Replace(sResult, "{Host}", sHost)
      GET_ERROR_DELETING_VALUE_MESSAGE = Replace(sResult, "{RegValue}", sRegValue)
  End Function
End Class

'******************************************************************************
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
'******************************************************************************
Function MomCreateObject(ByVal sProgramId)
  Dim oError
  Set oError = New Error
  
On Error Resume Next
Set MomCreateObject = CreateObject(sProgramId)
oError.Save
On Error Goto 0

If oError.Number &lt;&gt; 0 Then ThrowScriptError "Unable to create automation object '" &amp; sProgramId &amp; "'", oError
End Function
'******************************************************************************
Function Quit()
WScript.Quit()
End Function

'******************************************************************************
Sub ThrowEmptyDiscoveryData()
Dim oAPI, oSQLDiscoveryData
Set oAPI = CreateObject("MOM.ScriptAPI")
set oSQLDiscoveryData = oAPI.CreateDiscoveryData(0, SourceId, ManagedEntityId)
Call oAPI.Return(oSQLDiscoveryData)

End Sub

'******************************************************************************
Function ThrowScriptErrorNoAbort(ByVal sMessage, ByVal oErr)
On Error Resume Next
If g_bSuppressThrowScriptErrorNoAbort = True Then
  g_bSuppressThrowScriptErrorNoAbort = False
Else
  Dim oAPITemp	
Set oAPITemp = MOMCreateObject("MOM.ScriptAPI")
  oAPITemp.LogScriptEvent "KMSDiscovery.vbs", 4001, 1, sMessage &amp; ". " &amp; oErr.m_sDescription
End if
End Function

'******************************************************************************
Function ThrowScriptError(Byval sMessage, ByVal oErr)
On Error Resume Next
ThrowScriptErrorNoAbort sMessage, oErr
Quit()
End Function
'******************************************************************************
Function WMIExecQueryRaw(ByVal sNamespace, ByVal sQuery)
'
' WMIExecQueryRaw :: Executes the WMI query and returns the result set.
'
'
  Dim oWMI, oQuery, nInstanceCount
  Dim e
  Set e = New Error
  On Error Resume Next
  Set oWMI = GetObject(sNamespace)
  
  e.Save
  On Error Goto 0
  If IsEmpty(oWMI) Then
      WScript.Echo "Unable to open WMI Namespace '" &amp; sNamespace

      ThrowScriptErrorNoAbort "Unable to open WMI Namespace '" &amp; sNamespace &amp; "'.  Check to see if the WMI service is enabled and running, and ensure this WMI namespace exists.", e
      ThrowEmptyDiscoveryData
  End If

  On Error Resume Next
  
  Set oQuery = oWMI.ExecQuery(sQuery)
  e.Save
  On Error Goto 0
  If IsEmpty(oQuery) Or e.Number &lt;&gt; 0 Then
      ThrowScriptError "The Query '" &amp; sQuery &amp; "' returned an invalid result set.  Please check to see if this is a valid WMI Query.", e
  End If

  Set WMIExecQueryRaw = oQuery

End Function


Function WMIExecQuery(ByVal sNamespace, ByVal sQuery)
'
' WMIExecQuery :: Executes the WMI query and returns the result set.
'
'
Dim oWMI, oQuery, nInstanceCount
Dim e
Set e = New Error
On Error Resume Next
Set oWMI = GetObject(sNamespace)

e.Save
On Error Goto 0
If IsEmpty(oWMI) Then
	WScript.Echo "Unable to open WMI Namespace '" &amp; sNamespace

	ThrowScriptErrorNoAbort "Unable to open WMI Namespace '" &amp; sNamespace &amp; "'.  Check to see if the WMI service is enabled and running, and ensure this WMI namespace exists.", e
	ThrowEmptyDiscoveryData
End If

On Error Resume Next

Set oQuery = oWMI.ExecQuery(sQuery)
e.Save
On Error Goto 0
If IsEmpty(oQuery) Or e.Number &lt;&gt; 0 Then
	ThrowScriptError "The Query '" &amp; sQuery &amp; "' returned an invalid result set.  Please check to see if this is a valid WMI Query.", e
End If

'Determine if we queried a valid WMI class - Count will return 0 or empty
On Error Resume Next
nInstanceCount = oQuery.Count
e.Save
On Error Goto 0
If e.Number &lt;&gt; 0 Then
	ThrowScriptError "The Query '" &amp; sQuery &amp; "' did not return any valid instances.  Please check to see if this is a valid WMI Query.", e
End If

Set WMIExecQuery = oQuery

End Function

Function WMIExecQuery2(ByVal sNamespace, ByVal sQuery)
'
' WMIExecQuery :: Executes the WMI query and returns the result set.
'
'
  Dim oQuery, nInstanceCount
  Dim e
  
  Set oQuery = WMIExecQueryRaw(sNamespace, sQuery)

  'Determine if we queried a valid WMI class - Count will return 0 or empty
  Set e = New Error
  On Error Resume Next
  nInstanceCount = oQuery.Count
  e.Save
  On Error Goto 0
  If e.Number &lt;&gt; 0 Then
      ThrowScriptError "The Query '" &amp; sQuery &amp; "' did not return any valid instances.  Please check to see if this is a valid WMI Query.", e
  End If
  
  Set WMIExecQuery = oQuery
  
End Function

Function IsValidWMIExecQuery(ByVal sNamespace, ByVal sQuery)
'
' IsValidWMIExecQuery :: Executes the WMI query and returns whether it was valid or not.
'
'
  Dim oQuery, nInstanceCount
  Dim e

  Set oQuery = WMIExecQueryRaw(sNamespace, sQuery)

  'Determine if we queried a valid WMI class - Count will return 0 or empty
  Set e = New Error
  On Error Resume Next
  nInstanceCount = oQuery.Count
  e.Save
  On Error Goto 0
  If e.Number &lt;&gt; 0 Then
      IsValidWMIExecQuery = False
  Else
      IsValidWMIExecQuery = True
  End If

End Function

'******************************************************************************

Function KMSActivationDiscovery( ByRef KMSVersion)

  Dim oSafeRegistry
  Dim bConnectedToRegistry
  Dim lResult

  KMSVersion = empty
  Set oSafeRegistry = New SafeRegistry
  bConnectedToRegistry = oSafeRegistry.Connect(TargetComputer)
  g_bSuppressThrowScriptErrorNoAbort = True ' no need to throw if there is no key or value
  'oSafeRegistry.SuppressionFlags = (oSafeRegistry.SUPPRESS_KEY_NOT_FOUND Or oSafeRegistry.SUPPRESS_VALUE_NOT_FOUND)
  KMSVersion = oSafeRegistry.ReadStringValue("SOFTWARE\Microsoft\Windows NT\CurrentVersion\SL", "KeyManagementServiceVersion", lResult)
  if 0 = lResult Then
    KMSActivationDiscovery = True
    Exit Function
  Else
    KMSActivationDiscovery = False   
  End If
                                            
  KMSVersion = oSafeRegistry.ReadStringValue("SOFTWARE\Microsoft\Windows NT\CurrentVersion\SoftwareProtectionPlatform", "KeyManagementServiceVersion", lResult)
  if 0 = lResult Then
    KMSActivationDiscovery = True
    Exit Function
  Else
    KMSActivationDiscovery = False   
  End If

End Function
'******************************************************************************

Function KMSServiceDiscovery(ByRef Name, ByRef ProcessId, ByRef State, ByRef DisplayName, ByRef PathName)

      Dim sNamespace
      sNamespace = "winmgmts://" &amp; TargetComputer &amp; "/root/cimv2"
      
      Dim oKMSServices, oService
      Set oKMSServices = WMIExecQuery(sNamespace, "SELECT Name, ProcessId, State, DisplayName, PathName FROM Win32_Service WHERE Name = 'sppsvc' OR Name = 'slsvc'")
      
      if oKMSServices.Count = 1 Then
          For Each oService in oKMSServices
              Name = oService.Name
              ProcessId = oService.ProcessId
              State = oService.State
              DisplayName = oService.DisplayName
              PathName = oService.PathName
          Next
          KMSServiceDiscovery = True
      Else 
          KMSServiceDiscovery = False          
      End If
      
End Function

'******************************************************************************

Function AddKmsServiceInstance(ByVal oDiscoveryData, ByVal KMSVer, ByRef oKMSServiceInstance)
  
  Dim oInstance
  
  Dim ServiceName, ProcessId, State, DisplayName, PathName
  Set oInstance = oDiscoveryData.CreateClassInstance("$MPElement[Name='Microsoft.Windows.KeyManagement.Service']$")
  
  call KMSServiceDiscovery(ServiceName, ProcessId, State, DisplayName, PathName)
  
  With oInstance
      .AddProperty "$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", TargetComputerID			   
      .AddProperty "$MPElement[Name='Microsoft.Windows.KeyManagement.Service']/KMSServicePath$", TargetComputerID
      .AddProperty "$MPElement[Name='Microsoft.Windows.KeyManagement.Service']/ProcessID$", ProcessId
      .AddProperty "$MPElement[Name='Microsoft.Windows.KeyManagement.Service']/ImageName$", ServiceName
      .AddProperty "$MPElement[Name='Microsoft.Windows.KeyManagement.Service']/FilePath$", PathName
      .AddProperty "$MPElement[Name='Microsoft.Windows.KeyManagement.Service']/ServiceName$", DisplayName					  
      .AddProperty "$MPElement[Name='Microsoft.Windows.KeyManagement.Service']/ServiceState$", State
      .AddProperty "$MPElement[Name='Microsoft.Windows.KeyManagement.Service']/KMSServiceVersion$", KMSVer
  End With 
      
  call oDiscoveryData.AddInstance(oInstance)
  
  set oKMSServiceInstance = oInstance
  AddKmsServiceInstance = True
          
End Function

'******************************************************************************

Sub Main()

  Dim oArgs
  Set oArgs = WScript.Arguments
  if oArgs.Count &lt;&gt; 4 Then
     Wscript.Quit -1
  End If
  
  SourceID = oArgs(0)
  ManagedEntityId = oArgs(1)
  TargetComputerID = oArgs(2)
  TargetComputer = oArgs(3)

  Dim KMSVer
  Dim oAPI, oDiscoveryData
   
  Set oAPI = MOMCreateObject("MOM.ScriptAPI")
  set oDiscoveryData = oAPI.CreateDiscoveryData(0, SourceId, ManagedEntityId)

  if KMSActivationDiscovery(KMSVer) = True  And Not IsEmpty(KMSVer)  And Len(KMSVer) &gt; 0 Then 
      Dim oKMSInst
      call AddKmsServiceInstance(oDiscoveryData, KMSVer, oKMSInst)
  End If
  oAPI.Return(oDiscoveryData) 

End Sub
</ScriptBody>
                <TimeoutSeconds>$Config/TimeoutSeconds$</TimeoutSeconds>
              </DataSource>
            </MemberModules>
            <Composition>
              <Node ID="DS" />
            </Composition>
          </Composite>
        </ModuleImplementation>
        <OutputType>System!System.Discovery.Data</OutputType>
      </DataSourceModuleType>
      <DataSourceModuleType ID="Microsoft.Windows.KeyManagement.Product.Discovery.DataSource" Accessibility="Public" Batching="false">
        <Configuration>
          <xsd:element name="IntervalSeconds" type="xsd:integer" />
          <xsd:element name="SyncTime" type="xsd:string" />
          <xsd:element name="ComputerID" type="xsd:string" />
          <xsd:element name="ComputerName" type="xsd:string" />
          <xsd:element name="ImageName" type="xsd:string" />
          <xsd:element name="TimeoutSeconds" type="xsd:int" />
        </Configuration>
        <OverrideableParameters>
          <OverrideableParameter ID="IntervalSeconds" Selector="$Config/IntervalSeconds$" ParameterType="int" />
          <OverrideableParameter ID="SyncTime" Selector="$Config/SyncTime$" ParameterType="string" />
          <OverrideableParameter ID="TimeoutSeconds" Selector="$Config/TimeoutSeconds$" ParameterType="int" />
        </OverrideableParameters>
        <ModuleImplementation Isolation="Any">
          <Composite>
            <MemberModules>
              <DataSource ID="DS" TypeID="Windows!Microsoft.Windows.TimedScript.DiscoveryProvider">
                <IntervalSeconds>$Config/IntervalSeconds$</IntervalSeconds>
                <SyncTime>$Config/SyncTime$</SyncTime>
                <ScriptName>KMSProductDiscovery.vbs</ScriptName>
                <Arguments>$MPElement$ $Target/Id$ $Config/ComputerID$ $Config/ComputerName$ $Config/ImageName$"</Arguments>
                <ScriptBody>
               
' Copyright (c) Microsoft Corporation. All rights reserved.
' Arguments:
'  0 - TargetComputer
'  1 - TargetComputerID
'  2 - SourceID
'  3 - ManagedEntityID
'  4 - ImageName
'
' This scripts discovers instances of the KMS Product class.
'
' This scripts uses WMI queries (WQL) to determine what level of supporting properties exist on the
' SoftwareLicensingProduct and SoftwareLicensingService WMI classes.
' Specifically we detect if these queries succeed/fail to determine support:
'  SELECT KeyManagementServiceTotalRequests FROM SoftwareLicensingService
'  SELECT KeyManagementServiceTotalRequests FROM SoftwareLicensingProduct
'

Option Explicit

Dim TargetComputer
Dim TargetComputerID
Dim SourceID
Dim ManagedEntityID
Dim ImageName

' it suppresses ThrowScriptErrorNoAbort only once. I need it for reading registry when registry key is not present
' and this is no error condition. 
Dim g_bSuppressThrowScriptErrorNoAbort

Call Main()
'******************************************************************************
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
'******************************************************************************
Class KMSProduct
  Private m_sProductSkuId
  Private m_sProductSkuName
  Private m_sProductSkuDescription
  Private m_lKMSCurrentCount
  Private m_sLastActivity
  Private m_lLastActivityYear
  Private m_lLastActivityMonth
  Private m_lLastActivityDay
  Private m_lLastActivityHour
  Private m_lLastActivityMinute
  Private m_lTotalRequests
  Private m_lIdleMinutes
  
  Public Sub Init(ByVal SkuId)
    Clear
    m_sProductSkuId = SkuId
  End Sub

  Public Sub Clear()
    m_sProductSkuId = ""
    m_sProductSkuName = ""
    m_sProductSkuDescription = ""
    m_lKMSCurrentCount = 0
    m_sLastActivity = Null
    m_lLastActivityYear = Null
    m_lLastActivityMonth = Null
    m_lLastActivityDay = Null
    m_lLastActivityHour = Null
    m_lLastActivityMinute = Null
    m_lTotalRequests = 0
    m_lIdleMinutes = 0
  End Sub
  
  Public Sub SetLastActivity( _
    ByVal sLastActivity, _
    ByVal sLastActivityYear, _
    ByVal sLastActivityMonth, _
    ByVal sLastActivityDay, _
    ByVal sLastActivityHour, _
    ByVal sLastActivityMinute _
    )
    m_sLastActivity         = sLastActivity
    m_lLastActivityYear     = CInt(sLastActivityYear)
    m_lLastActivityMonth    = CInt(sLastActivityMonth)
    m_lLastActivityDay      = CInt(sLastActivityDay)
    m_lLastActivityHour     = CInt(sLastActivityHour)
    m_lLastActivityMinute   = CInt(sLastActivityMinute)
  End Sub
    
    Public Sub CalculateIdleMinutes()
        If IsNull(m_sLastActivity) Then
            SetLastActivityToCurrentTime
            Exit Sub
        Else
            Dim NowTime
            NowTime = Now()
            m_lIdleMinutes = DateDiff("n", m_sLastActivity, NowTime)
        End If
    End Sub

  Public Sub SetLastActivityToCurrentTime()

    Dim NowTime
    NowTime = Now()
    
    SetLastActivity NowTime, Year(NowTime), Month(NowTime), Day(NowTime), Hour(NowTime), Minute(NowTime)  
    m_lIdleMinutes = 0
 
  End Sub
  

'
' Read-Only Properties
'  
  Public Property Get ProductSkuId()
    ProductSkuId = m_sProductSkuId
  End Property 
  
  Public Property Get LastActivity()
    LastActivity = m_sLastActivity
  End Property 

  Public Property Get LastActivityYear()
    LastActivityYear = m_lLastActivityYear
  End Property 

  Public Property Get LastActivityMonth()
    LastActivityMonth = m_lLastActivityMonth
  End Property 

  Public Property Get LastActivityDay()
    LastActivityDay = m_lLastActivityDay
  End Property 

  Public Property Get LastActivityHour()
    LastActivityHour = m_lLastActivityHour
  End Property 

  Public Property Get LastActivityMinute()
    LastActivityMinute = m_lLastActivityMinute
  End Property 

  Public Property Get IdleMinutes()
    IdleMinutes = m_lIdleMinutes 
  End Property 

'
' Read/Write Properties
'
  Public Property Get ProductSkuName()
    ProductSkuName = m_sProductSkuName
  End Property 
  
  Public Property Let ProductSkuName(ByVal sSkuName)
    m_sProductSkuName = sSkuName
  End Property
 
  Public Property Get ProductSkuDescription()
    ProductSkuDescription = m_sProductSkuDescription
  End Property
  
  Public Property Let ProductSkuDescription(ByVal sSkuDescription)
    m_sProductSkuDescription = sSkuDescription
  End Property
  
  Public Property Get KMSCurrentCount()
    KMSCurrentCount= m_lKMSCurrentCount
  End Property 

  Public Property Let KMSCurrentCount(ByVal lCount)
    m_lKMSCurrentCount = lCount
  End Property

  Public Property Get TotalRequests()
    TotalRequests = m_lTotalRequests 
  End Property 

  Public Property Let TotalRequests(ByVal lRequests)
    m_lTotalRequests = lRequests
  End Property

End Class
'******************************************************************************
Function MomCreateObject(ByVal sProgramId)
  Dim oError
  Set oError = New Error
  
On Error Resume Next
Set MomCreateObject = CreateObject(sProgramId)
oError.Save
On Error Goto 0

If oError.Number &lt;&gt; 0 Then ThrowScriptError "Unable to create automation object '" &amp; sProgramId &amp; "'", oError
End Function
'******************************************************************************
Function Quit()
WScript.Quit()
End Function

'******************************************************************************
Sub ThrowEmptyDiscoveryData()
Dim oAPI, oSQLDiscoveryData
Set oAPI = CreateObject("MOM.ScriptAPI")
set oSQLDiscoveryData = oAPI.CreateDiscoveryData(0, SourceId, ManagedEntityId)
Call oAPI.Return(oSQLDiscoveryData)

End Sub

'******************************************************************************
Function ThrowScriptErrorNoAbort(ByVal sMessage, ByVal oErr)
On Error Resume Next
If g_bSuppressThrowScriptErrorNoAbort = True Then
  g_bSuppressThrowScriptErrorNoAbort = False
Else
  Dim oAPITemp	
Set oAPITemp = MOMCreateObject("MOM.ScriptAPI")
  oAPITemp.LogScriptEvent "KMSProductDiscovery.vbs", 4001, 1, sMessage &amp; ". " &amp; oErr.m_sDescription
End if
End Function

'******************************************************************************
Function ThrowScriptError(Byval sMessage, ByVal oErr)
On Error Resume Next
ThrowScriptErrorNoAbort sMessage, oErr
Quit()
End Function
'******************************************************************************
Function WMIExecQueryRaw(ByVal sNamespace, ByVal sQuery)
'
' WMIExecQueryRaw :: Executes the WMI query and returns the result set.
'
'
  Dim oWMI, oQuery, nInstanceCount
  Dim e
  Set e = New Error
  On Error Resume Next
  Set oWMI = GetObject(sNamespace)
  
  e.Save
  On Error Goto 0
  If IsEmpty(oWMI) Then
      WScript.Echo "Unable to open WMI Namespace '" &amp; sNamespace

      ThrowScriptErrorNoAbort "Unable to open WMI Namespace '" &amp; sNamespace &amp; "'.  Check to see if the WMI service is enabled and running, and ensure this WMI namespace exists.", e
      ThrowEmptyDiscoveryData
  End If

  On Error Resume Next
  
  Set oQuery = oWMI.ExecQuery(sQuery)
  e.Save
  On Error Goto 0
  If IsEmpty(oQuery) Or e.Number &lt;&gt; 0 Then
      ThrowScriptError "The Query '" &amp; sQuery &amp; "' returned an invalid result set.  Please check to see if this is a valid WMI Query.", e
  End If

  Set WMIExecQueryRaw = oQuery

End Function


Function WMIExecQuery(ByVal sNamespace, ByVal sQuery)
'
' WMIExecQuery :: Executes the WMI query and returns the result set.
'
'
Dim oWMI, oQuery, nInstanceCount
Dim e
Set e = New Error
On Error Resume Next
Set oWMI = GetObject(sNamespace)

e.Save
On Error Goto 0
If IsEmpty(oWMI) Then
	WScript.Echo "Unable to open WMI Namespace '" &amp; sNamespace

	ThrowScriptErrorNoAbort "Unable to open WMI Namespace '" &amp; sNamespace &amp; "'.  Check to see if the WMI service is enabled and running, and ensure this WMI namespace exists.", e
	ThrowEmptyDiscoveryData
End If

On Error Resume Next

Set oQuery = oWMI.ExecQuery(sQuery)
e.Save
On Error Goto 0
If IsEmpty(oQuery) Or e.Number &lt;&gt; 0 Then
	ThrowScriptError "The Query '" &amp; sQuery &amp; "' returned an invalid result set.  Please check to see if this is a valid WMI Query.", e
End If

'Determine if we queried a valid WMI class - Count will return 0 or empty
On Error Resume Next
nInstanceCount = oQuery.Count
e.Save
On Error Goto 0
If e.Number &lt;&gt; 0 Then
	ThrowScriptError "The Query '" &amp; sQuery &amp; "' did not return any valid instances.  Please check to see if this is a valid WMI Query.", e
End If

Set WMIExecQuery = oQuery

End Function

Function WMIExecQuery2(ByVal sNamespace, ByVal sQuery)
'
' WMIExecQuery :: Executes the WMI query and returns the result set.
'
'
  Dim oQuery, nInstanceCount
  Dim e
  
  Set oQuery = WMIExecQueryRaw(sNamespace, sQuery)

  'Determine if we queried a valid WMI class - Count will return 0 or empty
  Set e = New Error
  On Error Resume Next
  nInstanceCount = oQuery.Count
  e.Save
  On Error Goto 0
  If e.Number &lt;&gt; 0 Then
      ThrowScriptError "The Query '" &amp; sQuery &amp; "' did not return any valid instances.  Please check to see if this is a valid WMI Query.", e
  End If
  
  Set WMIExecQuery = oQuery
  
End Function

Function IsValidWMIExecQuery(ByVal sNamespace, ByVal sQuery)
'
' IsValidWMIExecQuery :: Executes the WMI query and returns whether it was valid or not.
'
'
  Dim oQuery, nInstanceCount
  Dim e

  Set oQuery = WMIExecQueryRaw(sNamespace, sQuery)

  'Determine if we queried a valid WMI class - Count will return 0 or empty
  Set e = New Error
  On Error Resume Next
  nInstanceCount = oQuery.Count
  e.Save
  On Error Goto 0
  If e.Number &lt;&gt; 0 Then
      IsValidWMIExecQuery = False
  Else
      IsValidWMIExecQuery = True
  End If

End Function

'******************************************************************************

Function KMSServiceSupportsServiceTotalRequestsCount()

  Dim sNamespace
  sNamespace = "winmgmts://" &amp; TargetComputer &amp; "/root/cimv2"

  KMSServiceSupportsServiceTotalRequestsCount = IsValidWMIExecQuery(sNamespace, "SELECT KeyManagementServiceTotalRequests FROM SoftwareLicensingService")

End Function

Function KMSServiceSupportsApplicationTotalRequestsCount()

  Dim sNamespace
  sNamespace = "winmgmts://" &amp; TargetComputer &amp; "/root/cimv2"

  KMSServiceSupportsApplicationTotalRequestsCount = IsValidWMIExecQuery(sNamespace, "SELECT KeyManagementServiceTotalRequests FROM SoftwareLicensingProduct")

End Function

'******************************************************************************

Function CollectKMSProductsUsingProductObject()

  Dim sNamespace

  sNamespace = "winmgmts://" &amp; TargetComputer &amp; "/root/cimv2"

  Dim oKMSProducts, oProduct
  Set oKMSProducts = WMIExecQuery(sNamespace, "SELECT ID, Name, Description, KeyManagementServiceCurrentCount FROM SoftwareLicensingProduct WHERE PartialProductKey &lt;&gt; null AND Description LIKE '%KMS%' AND NOT Description LIKE '%KMSCLIENT%'")
 
  If oKMSProducts.Count = 0 Then
      CollectKMSProductsUsingProductObject = Null
      Exit Function
  End If
   
  Dim arrKMSProducts()

  ReDim arrKMSProducts(oKMSProducts.Count)  
  Dim iProduct

  iProduct = 0
  For Each oProduct in oKMSProducts

    Dim oKMSProduct
    Set oKMSProduct = New KMSProduct

    oKMSProduct.Init oProduct.ID
    oKMSProduct.ProductSkuName = oProduct.Name
    oKmsProduct.ProductSkuDescription = oProduct.Description
    oKMSProduct.KMSCurrentCount = oProduct.KeyManagementServiceCurrentCount    

    Set arrKMSProducts(iProduct) = oKMSProduct

    iProduct = iProduct + 1

  Next

  CollectKMSProductsUsingProductObject = arrKMSProducts
End Function

Function CollectKMSProductsUsingServiceObject()

  Dim sNamespace

  sNamespace = "winmgmts://" &amp; TargetComputer &amp; "/root/cimv2"

  Dim oKMSServices, oService
  Dim KMSCurrentCount
  Set oKMSServices = WMIExecQuery(sNamespace, "SELECT KeyManagementServiceCurrentCount FROM SoftwareLicensingService")
  
  if oKMSServices.Count &lt;&gt; 1 Then
      KmsProductDiscoveryUsingService = False
      Exit Function
  Else
      For Each oService in oKMSServices
          KMSCurrentCount = oService.KeyManagementServiceCurrentCount
      Next
  End If

  Dim oKMSProducts, oProduct

  Set oKMSProducts = WMIExecQuery(sNamespace, "SELECT ID, Name, Description FROM SoftwareLicensingProduct WHERE PartialProductKey &lt;&gt; null And Description LIKE '%KMS%' AND NOT Description LIKE '%KMSCLIENT%'")

  if oKMSProducts.Count = 0 Then
      CollectKMSProductsUsingServiceObject = Null
      Exit Function
  End If
  
  Dim arrKMSProducts()

  ReDim arrKMSProducts(oKMSProducts.Count)  
  Dim iProduct

  iProduct = 0
  For Each oProduct in oKMSProducts

    Dim oKMSProduct
    Set oKMSProduct = New KMSProduct

    oKMSProduct.Init oProduct.ID
    oKMSProduct.ProductSkuName = oProduct.Name
    oKmsProduct.ProductSkuDescription = oProduct.Description
    oKMSProduct.KMSCurrentCount = KMSCurrentCount    

    Set arrKMSProducts(iProduct) = oKMSProduct

    iProduct = iProduct + 1

  Next

  CollectKMSProductsUsingServiceObject = arrKMSProducts
End Function

Function AddKmsProductInstancesToDiscovery(ByRef arrProducts, ByVal oDiscoveryData)
    Dim oProduct, iProduct

    For iProduct = LBound(arrProducts) To (UBound(arrProducts) - 1)
        Set oProduct = arrProducts(iProduct)

        Dim oInstance

        Set oInstance = oDiscoveryData.CreateClassInstance("$MPElement[Name='Microsoft.Windows.KeyManagement.Product']$")

        With oInstance
          .AddProperty "$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", TargetComputerID			   
          .AddProperty "$MPElement[Name='Microsoft.Windows.KeyManagement.Service']/ImageName$", ImageName
          .AddProperty "$MPElement[Name='Microsoft.Windows.KeyManagement.Product']/ProductSkuId$", oProduct.ProductSkuID
          .AddProperty "$MPElement[Name='Microsoft.Windows.KeyManagement.Product']/ProductSkuName$", oProduct.ProductSkuName
          .AddProperty "$MPElement[Name='Microsoft.Windows.KeyManagement.Product']/ProductSkuDescription$", oProduct.ProductSkuDescription
          .AddProperty "$MPElement[Name='Microsoft.Windows.KeyManagement.Product']/KMSCurrentCount$", oProduct.KMSCurrentCount
          .AddProperty "$MPElement[Name='System!System.Entity']/DisplayName$", oProduct.ProductSkuDescription
        End With

        Call oDiscoveryData.AddInstance(oInstance)
    Next

    AddKmsProductInstancesToDiscovery = True

End Function

'******************************************************************************

Sub Main()

  Dim oArgs
  Set oArgs = WScript.Arguments
  if oArgs.Count &lt;&gt; 5 Then
     Wscript.Quit -1
  End If
  
  SourceID = oArgs(0)
  ManagedEntityId = oArgs(1)
  TargetComputerID = oArgs(2)
  TargetComputer = oArgs(3)
  ImageName = oArgs(4)

  Dim KMSVer
  Dim oAPI, oDiscoveryData
  
  Dim arrProducts
   
  Set oAPI = MOMCreateObject("MOM.ScriptAPI")
  set oDiscoveryData = oAPI.CreateDiscoveryData(0, SourceId, ManagedEntityId)
    
  if KMSServiceSupportsApplicationTotalRequestsCount() = True Then
    arrProducts = CollectKMSProductsUsingProductObject()
  Else
    if KMSServiceSupportsServiceTotalRequestsCount() = True Then
      arrProducts = CollectKMSProductsUsingServiceObject()
    Else
    End If
  End If
  
  If Not IsNull(arrProducts) Then
    Call AddKmsProductInstancesToDiscovery(arrProducts, oDiscoveryData)
  End If

  oAPI.Return(oDiscoveryData) 

End Sub
</ScriptBody>
                <TimeoutSeconds>$Config/TimeoutSeconds$</TimeoutSeconds>
              </DataSource>
            </MemberModules>
            <Composition>
              <Node ID="DS" />
            </Composition>
          </Composite>
        </ModuleImplementation>
        <OutputType>System!System.Discovery.Data</OutputType>
      </DataSourceModuleType>
      <DataSourceModuleType ID="Microsoft.Windows.KeyManagement.Product.UpdateLastActivity.Discovery.DataSource" Accessibility="Public" Batching="false">
        <Configuration>
          <xsd:element name="IntervalSeconds" type="xsd:integer" />
          <xsd:element name="SyncTime" type="xsd:string" />
          <xsd:element name="ComputerID" type="xsd:string" />
          <xsd:element name="ComputerName" type="xsd:string" />
          <xsd:element name="ImageName" type="xsd:string" />
          <xsd:element name="ProductSkuId" type="xsd:string" />
          <xsd:element name="TotalRequests" type="xsd:string" />
          <xsd:element name="LastActivityYear" type="xsd:string" />
          <xsd:element name="LastActivityMonth" type="xsd:string" />
          <xsd:element name="LastActivityDay" type="xsd:string" />
          <xsd:element name="LastActivityHour" type="xsd:string" />
          <xsd:element name="LastActivityMinute" type="xsd:string" />
          <xsd:element name="TimeoutSeconds" type="xsd:int" />
        </Configuration>
        <OverrideableParameters>
          <OverrideableParameter ID="IntervalSeconds" Selector="$Config/IntervalSeconds$" ParameterType="int" />
          <OverrideableParameter ID="SyncTime" Selector="$Config/SyncTime$" ParameterType="string" />
          <OverrideableParameter ID="TimeoutSeconds" Selector="$Config/TimeoutSeconds$" ParameterType="int" />
        </OverrideableParameters>
        <ModuleImplementation Isolation="Any">
          <Composite>
            <MemberModules>
              <DataSource ID="DU" TypeID="Windows!Microsoft.Windows.TimedScript.DiscoveryProvider">
                <IntervalSeconds>$Config/IntervalSeconds$</IntervalSeconds>
                <SyncTime>$Config/SyncTime$</SyncTime>
                <ScriptName>KMSProductUpdateLastActivity.vbs</ScriptName>
                <Arguments>$MPElement$ $Target/Id$ $Config/ComputerID$ $Config/ComputerName$ $Config/ImageName$ $Config/ProductSkuId$ $Config/TotalRequests$ $Config/LastActivityYear$ $Config/LastActivityMonth$ $Config/LastActivityDay$ $Config/LastActivityHour$ $Config/LastActivityMinute$"</Arguments>
                <ScriptBody>

' Copyright (c) Microsoft Corporation. All rights reserved.
' Arguments
'  0 - TargetComputer
'  1 - TargetComputerID
'  2 - SourceID
'  3 - ManagedEntityID
'  4 - ImageName
'  5 - ProductSkuId
'  6 - TotalRequests
'  7 - LastActivityYear
'  8 - LastActivityMonth
'  9 - LastActivityDay
' 10 - LastActivityHour
' 11 - LastActivityMinute
'
' This scripts discovers the "IdleMinutes" and "LastActivity" property of instances of the KMS Product class.
'
' The arguments passed to this script should be
'  1) All
'  2) 0 through 5
'  or
'  3) 0 through 6
'
' The basic idea of the script is to compare the current value of "TotalRequests" with the previous value
' so that we can determine if it has changed.  If it has changed then we update the value of LastActivity to the
' current time and set IdleMinutes to 0.  If the value of TotalRequests has not changed then we will
' calculate the IdleMinutes based off of the input values supplied as parameters. 
'
' The LastActivity is broken into discrete elements so we do not have to rely on any locale-specific conversions.
'

Option Explicit

Dim TargetComputer
Dim TargetComputerID
Dim SourceID
Dim ManagedEntityID
Dim ImageName
Dim ProductSkuId
Dim TotalRequests
Dim LastActivityYear
Dim LastActivityMonth
Dim LastActivityDay
Dim LastActivityHour
Dim LastActivityMinute

' it suppresses ThrowScriptErrorNoAbort only once. I need it for reading registry when registry key is not present
' and this is no error condition. 
Dim g_bSuppressThrowScriptErrorNoAbort

Call Main()
'******************************************************************************
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
'******************************************************************************
Class KMSProduct
  Private m_sProductSkuId
  Private m_sProductSkuName
  Private m_sProductSkuDescription
  Private m_lKMSCurrentCount
  Private m_sLastActivity
  Private m_lLastActivityYear
  Private m_lLastActivityMonth
  Private m_lLastActivityDay
  Private m_lLastActivityHour
  Private m_lLastActivityMinute
  Private m_lTotalRequests
  Private m_lIdleMinutes
  
  Public Sub Init(ByVal SkuId)
    Clear
    m_sProductSkuId = SkuId
  End Sub

  Public Sub Clear()
    m_sProductSkuId = ""
    m_sProductSkuName = ""
    m_sProductSkuDescription = ""
    m_lKMSCurrentCount = 0
    m_sLastActivity = Null
    m_lLastActivityYear = Null
    m_lLastActivityMonth = Null
    m_lLastActivityDay = Null
    m_lLastActivityHour = Null
    m_lLastActivityMinute = Null
    m_lTotalRequests = 0
    m_lIdleMinutes = 0
  End Sub
  
  Public Sub SetLastActivity( _
    ByVal sLastActivity, _
    ByVal sLastActivityYear, _
    ByVal sLastActivityMonth, _
    ByVal sLastActivityDay, _
    ByVal sLastActivityHour, _
    ByVal sLastActivityMinute _
    )
    m_sLastActivity         = sLastActivity
    m_lLastActivityYear     = CInt(sLastActivityYear)
    m_lLastActivityMonth    = CInt(sLastActivityMonth)
    m_lLastActivityDay      = CInt(sLastActivityDay)
    m_lLastActivityHour     = CInt(sLastActivityHour)
    m_lLastActivityMinute   = CInt(sLastActivityMinute)
  End Sub
    
    Public Sub CalculateIdleMinutes()
        If IsNull(m_sLastActivity) Then
            SetLastActivityToCurrentTime
            Exit Sub
        Else
            Dim NowTime
            NowTime = Now()
            m_lIdleMinutes = DateDiff("n", m_sLastActivity, NowTime)
        End If
    End Sub

  Public Sub SetLastActivityToCurrentTime()

    Dim NowTime
    NowTime = Now()
    
    SetLastActivity NowTime, Year(NowTime), Month(NowTime), Day(NowTime), Hour(NowTime), Minute(NowTime)  
    m_lIdleMinutes = 0
 
  End Sub
  

'
' Read-Only Properties
'  
  Public Property Get ProductSkuId()
    ProductSkuId = m_sProductSkuId
  End Property 
  
  Public Property Get LastActivity()
    LastActivity = m_sLastActivity
  End Property 

  Public Property Get LastActivityYear()
    LastActivityYear = m_lLastActivityYear
  End Property 

  Public Property Get LastActivityMonth()
    LastActivityMonth = m_lLastActivityMonth
  End Property 

  Public Property Get LastActivityDay()
    LastActivityDay = m_lLastActivityDay
  End Property 

  Public Property Get LastActivityHour()
    LastActivityHour = m_lLastActivityHour
  End Property 

  Public Property Get LastActivityMinute()
    LastActivityMinute = m_lLastActivityMinute
  End Property 

  Public Property Get IdleMinutes()
    IdleMinutes = m_lIdleMinutes 
  End Property 

'
' Read/Write Properties
'
  Public Property Get ProductSkuName()
    ProductSkuName = m_sProductSkuName
  End Property 
  
  Public Property Let ProductSkuName(ByVal sSkuName)
    m_sProductSkuName = sSkuName
  End Property
 
  Public Property Get ProductSkuDescription()
    ProductSkuDescription = m_sProductSkuDescription
  End Property
  
  Public Property Let ProductSkuDescription(ByVal sSkuDescription)
    m_sProductSkuDescription = sSkuDescription
  End Property
  
  Public Property Get KMSCurrentCount()
    KMSCurrentCount= m_lKMSCurrentCount
  End Property 

  Public Property Let KMSCurrentCount(ByVal lCount)
    m_lKMSCurrentCount = lCount
  End Property

  Public Property Get TotalRequests()
    TotalRequests = m_lTotalRequests 
  End Property 

  Public Property Let TotalRequests(ByVal lRequests)
    m_lTotalRequests = lRequests
  End Property

End Class
'******************************************************************************
Function MomCreateObject(ByVal sProgramId)
  Dim oError
  Set oError = New Error
  
On Error Resume Next
Set MomCreateObject = CreateObject(sProgramId)
oError.Save
On Error Goto 0

If oError.Number &lt;&gt; 0 Then ThrowScriptError "Unable to create automation object '" &amp; sProgramId &amp; "'", oError
End Function
'******************************************************************************
Function Quit()
WScript.Quit()
End Function

'******************************************************************************
Sub ThrowEmptyDiscoveryData()
Dim oAPI, oSQLDiscoveryData
Set oAPI = CreateObject("MOM.ScriptAPI")
set oSQLDiscoveryData = oAPI.CreateDiscoveryData(0, SourceId, ManagedEntityId)
Call oAPI.Return(oSQLDiscoveryData)

End Sub

'******************************************************************************
Function ThrowScriptErrorNoAbort(ByVal sMessage, ByVal oErr)
On Error Resume Next
If g_bSuppressThrowScriptErrorNoAbort = True Then
  g_bSuppressThrowScriptErrorNoAbort = False
Else
  Dim oAPITemp	
Set oAPITemp = MOMCreateObject("MOM.ScriptAPI")
  oAPITemp.LogScriptEvent "KMSProductUpdateLastActivity.vbs", 4001, 1, sMessage &amp; ". " &amp; oErr.m_sDescription
End if
End Function

'******************************************************************************
Function ThrowScriptError(Byval sMessage, ByVal oErr)
On Error Resume Next
ThrowScriptErrorNoAbort sMessage, oErr
Quit()
End Function
'******************************************************************************
Function WMIExecQueryRaw(ByVal sNamespace, ByVal sQuery)
'
' WMIExecQueryRaw :: Executes the WMI query and returns the result set.
'
'
  Dim oWMI, oQuery, nInstanceCount
  Dim e
  Set e = New Error
  On Error Resume Next
  Set oWMI = GetObject(sNamespace)
  
  e.Save
  On Error Goto 0
  If IsEmpty(oWMI) Then
      WScript.Echo "Unable to open WMI Namespace '" &amp; sNamespace

      ThrowScriptErrorNoAbort "Unable to open WMI Namespace '" &amp; sNamespace &amp; "'.  Check to see if the WMI service is enabled and running, and ensure this WMI namespace exists.", e
      ThrowEmptyDiscoveryData
  End If

  On Error Resume Next
  
  Set oQuery = oWMI.ExecQuery(sQuery)
  e.Save
  On Error Goto 0
  If IsEmpty(oQuery) Or e.Number &lt;&gt; 0 Then
      ThrowScriptError "The Query '" &amp; sQuery &amp; "' returned an invalid result set.  Please check to see if this is a valid WMI Query.", e
  End If

  Set WMIExecQueryRaw = oQuery

End Function


Function WMIExecQuery(ByVal sNamespace, ByVal sQuery)
'
' WMIExecQuery :: Executes the WMI query and returns the result set.
'
'
Dim oWMI, oQuery, nInstanceCount
Dim e
Set e = New Error
On Error Resume Next
Set oWMI = GetObject(sNamespace)

e.Save
On Error Goto 0
If IsEmpty(oWMI) Then
	WScript.Echo "Unable to open WMI Namespace '" &amp; sNamespace

	ThrowScriptErrorNoAbort "Unable to open WMI Namespace '" &amp; sNamespace &amp; "'.  Check to see if the WMI service is enabled and running, and ensure this WMI namespace exists.", e
	ThrowEmptyDiscoveryData
End If

On Error Resume Next

Set oQuery = oWMI.ExecQuery(sQuery)
e.Save
On Error Goto 0
If IsEmpty(oQuery) Or e.Number &lt;&gt; 0 Then
	ThrowScriptError "The Query '" &amp; sQuery &amp; "' returned an invalid result set.  Please check to see if this is a valid WMI Query.", e
End If

'Determine if we queried a valid WMI class - Count will return 0 or empty
On Error Resume Next
nInstanceCount = oQuery.Count
e.Save
On Error Goto 0
If e.Number &lt;&gt; 0 Then
	ThrowScriptError "The Query '" &amp; sQuery &amp; "' did not return any valid instances.  Please check to see if this is a valid WMI Query.", e
End If

Set WMIExecQuery = oQuery

End Function

Function WMIExecQuery2(ByVal sNamespace, ByVal sQuery)
'
' WMIExecQuery :: Executes the WMI query and returns the result set.
'
'
  Dim oQuery, nInstanceCount
  Dim e
  
  Set oQuery = WMIExecQueryRaw(sNamespace, sQuery)

  'Determine if we queried a valid WMI class - Count will return 0 or empty
  Set e = New Error
  On Error Resume Next
  nInstanceCount = oQuery.Count
  e.Save
  On Error Goto 0
  If e.Number &lt;&gt; 0 Then
      ThrowScriptError "The Query '" &amp; sQuery &amp; "' did not return any valid instances.  Please check to see if this is a valid WMI Query.", e
  End If
  
  Set WMIExecQuery = oQuery
  
End Function

Function IsValidWMIExecQuery(ByVal sNamespace, ByVal sQuery)
'
' IsValidWMIExecQuery :: Executes the WMI query and returns whether it was valid or not.
'
'
  Dim oQuery, nInstanceCount
  Dim e

  Set oQuery = WMIExecQueryRaw(sNamespace, sQuery)

  'Determine if we queried a valid WMI class - Count will return 0 or empty
  Set e = New Error
  On Error Resume Next
  nInstanceCount = oQuery.Count
  e.Save
  On Error Goto 0
  If e.Number &lt;&gt; 0 Then
      IsValidWMIExecQuery = False
  Else
      IsValidWMIExecQuery = True
  End If

End Function

'******************************************************************************

Function KMSServiceSupportsServiceTotalRequestsCount()

  Dim sNamespace
  sNamespace = "winmgmts://" &amp; TargetComputer &amp; "/root/cimv2"

  KMSServiceSupportsServiceTotalRequestsCount = IsValidWMIExecQuery(sNamespace, "SELECT KeyManagementServiceTotalRequests FROM SoftwareLicensingService")

End Function

Function KMSServiceSupportsApplicationTotalRequestsCount()

  Dim sNamespace
  sNamespace = "winmgmts://" &amp; TargetComputer &amp; "/root/cimv2"

  KMSServiceSupportsApplicationTotalRequestsCount = IsValidWMIExecQuery(sNamespace, "SELECT KeyManagementServiceTotalRequests FROM SoftwareLicensingProduct")

End Function

'******************************************************************************

Function AddLastActivityToProductInstance(ByRef oInstance)
  Dim NowTime

  NowTime = Now()

  With oInstance
    .AddProperty "$MPElement[Name='Microsoft.Windows.KeyManagement.Product']/LastActivity$", NowTime
    .AddProperty "$MPElement[Name='Microsoft.Windows.KeyManagement.Product']/LastActivityYear$", Year(NowTime)
    .AddProperty "$MPElement[Name='Microsoft.Windows.KeyManagement.Product']/LastActivityMonth$", Month(NowTime)
    .AddProperty "$MPElement[Name='Microsoft.Windows.KeyManagement.Product']/LastActivityDay$", Day(NowTime)
    .AddProperty "$MPElement[Name='Microsoft.Windows.KeyManagement.Product']/LastActivityHour$", Hour(NowTime)
    .AddProperty "$MPElement[Name='Microsoft.Windows.KeyManagement.Product']/LastActivityMinute$", Minute(NowTime)
  End With
  
  Call AddIdleMinutesToProductInstance("0", oInstance)
End Function

Function AddIdleMinutesToProductInstance(ByVal IdleMinutes, ByRef oInstance)

  With oInstance
    .AddProperty "$MPElement[Name='Microsoft.Windows.KeyManagement.Product']/IdleMinutes$", IdleMinutes  
  End With
  
End Function

Function CalculateIdleMinutes()
  Dim LastActivityDate
  Dim NowTime

  LastActivityDate = DateSerial(CInt(LastActivityYear), CInt(LastActivityMonth), CInt(LastActivityDay))
  LastActivityDate = DateAdd("h", CInt(LastActivityHour), LastActivityDate)
  LastActivityDate = DateAdd("n", CInt(LastActivityMinute), LastActivityDate)
  
  NowTime = Now()

  CalculateIdleMinutes = DateDiff("n", LastActivityDate, NowTime)   
  
End Function

Function UpdateProductInstanceUsingProductObject(ByRef oKMSProduct)

    Dim sNamespace
    sNamespace = "winmgmts://" &amp; TargetComputer &amp; "/root/cimv2"
    
    Dim oKMSProducts
    Dim oProduct
    Dim KMSTotalRequests
    Dim KMSCurrentCount
    Set oKMSProducts = WMIExecQuery(sNamespace, "SELECT ID, KeyManagementServiceTotalRequests, KeyManagementServiceCurrentCount FROM SoftwareLicensingProduct WHERE ID = '" &amp; ProductSkuId &amp; "'")
    
    if oKMSProducts.Count &lt;&gt; 1 Then
        UpdateProductInstanceUsingProductObject = False
        Exit Function
    Else
        For Each oProduct in oKMSProducts
          KMSTotalRequests = oProduct.KeyManagementServiceTotalRequests
          KMSCurrentCount = oProduct.KeyManagementServiceCurrentCount
        Next
    End If

    oKMSProduct.TotalRequests = KMSTotalRequests
    oKMSProduct.KMSCurrentCount = KMSCurrentCount
    UpdateProductInstanceUsingProductObject = True

End Function

Function UpdateProductInstanceUsingServiceObject(ByRef oKMSProduct)

    Dim sNamespace
    sNamespace = "winmgmts://" &amp; TargetComputer &amp; "/root/cimv2"
    
    Dim oKMSServices
    Dim oService
    Dim KMSTotalRequests
    Dim KMSCurrentCount
    Set oKMSServices = WMIExecQuery(sNamespace, "SELECT KeyManagementServiceTotalRequests, KeyManagementServiceCurrentCount FROM SoftwareLicensingService")
    
    if oKMSServices.Count &lt;&gt; 1 Then
        UpdateProductInstanceUsingServiceObject = False
        Exit Function
    Else
        For Each oService in oKMSServices
          KMSTotalRequests = oService.KeyManagementServiceTotalRequests
          KMSCurrentCount = oService.KeyManagementServiceCurrentCount
        Next
    End If

    oKMSProduct.TotalRequests = KMSTotalRequests
    oKMSProduct.KMSCurrentCount = KMSCurrentCount
    UpdateProductInstanceUsingServiceObject = True
    
End Function

Function AddProductInstanceToDiscovery(ByVal oKMSProduct, ByRef oDiscoveryData)

    Dim oInstance

    Set oInstance = oDiscoveryData.CreateClassInstance("$MPElement[Name='Microsoft.Windows.KeyManagement.Product']$")
    With oInstance
    .AddProperty "$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$",                        TargetComputerID			   
    .AddProperty "$MPElement[Name='Microsoft.Windows.KeyManagement.Product']/ProductSkuId$",         ProductSkuId
    .AddProperty "$MPElement[Name='Microsoft.Windows.KeyManagement.Service']/ImageName$",            ImageName
    .AddProperty "$MPElement[Name='Microsoft.Windows.KeyManagement.Product']/TotalRequests$",        oKMSProduct.TotalRequests
    .AddProperty "$MPElement[Name='Microsoft.Windows.KeyManagement.Product']/KMSCurrentCount$",      oKMSProduct.KMSCurrentCount
    .AddProperty "$MPElement[Name='Microsoft.Windows.KeyManagement.Product']/LastActivity$",         oKMSProduct.LastActivity
    .AddProperty "$MPElement[Name='Microsoft.Windows.KeyManagement.Product']/LastActivityYear$",     oKMSProduct.LastActivityYear
    .AddProperty "$MPElement[Name='Microsoft.Windows.KeyManagement.Product']/LastActivityMonth$",    oKMSProduct.LastActivityMonth
    .AddProperty "$MPElement[Name='Microsoft.Windows.KeyManagement.Product']/LastActivityDay$",      oKMSProduct.LastActivityDay
    .AddProperty "$MPElement[Name='Microsoft.Windows.KeyManagement.Product']/LastActivityHour$",     oKMSProduct.LastActivityHour
    .AddProperty "$MPElement[Name='Microsoft.Windows.KeyManagement.Product']/LastActivityMinute$",   oKMSProduct.LastActivityMinute
    .AddProperty "$MPElement[Name='Microsoft.Windows.KeyManagement.Product']/IdleMinutes$",          oKMSProduct.IdleMinutes
    End With
    
    Call oDiscoveryData.AddInstance(oInstance)
    
    AddProductInstanceToDiscovery = True
End Function

'******************************************************************************

Sub Main()

    Dim oArgs
    Set oArgs = WScript.Arguments

    if oArgs.Count &lt; 4 Then
        Wscript.Quit -1
    End If
   
    SourceID            = oArgs(0)
    ManagedEntityId     = oArgs(1)
    TargetComputerID    = oArgs(2)
    TargetComputer      = oArgs(3)
    ImageName           = oArgs(4)
    ProductSkuId        = oArgs(5)    
  
    if oArgs.Count &gt; 6 Then
        TotalRequests = oArgs(6)

        if (Trim(TotalRequests) = "") Then
            TotalRequests = null
        End If
    Else
        TotalRequests = null
    End If
  
    if oArgs.Count &gt; 7 Then
        If oArgs.Count &lt;&gt; 12 Then
            Wscript.Quit -1
        End If
    
        LastActivityYear = oArgs(7)
        LastActivityMonth = oArgs(8)
        LastActivityDay = oArgs(9)
        LastActivityHour = oArgs(10)
        LastActivityMinute = oArgs(11)
    Else
        LastActivityYear = null
        LastActivityMonth = null
        LastActivityDay = null
        LastActivityHour = null
        LastActivityMinute = null
    End If
  
    Dim KMSVer
    Dim oAPI
    Dim oDiscoveryData
  
    Dim oKMSProduct
    Set oKMSProduct = New KMSProduct
  
    oKMSProduct.Init ProductSkuId
  
    If Not IsNull(LastActivityYear) Then
        Dim LastActivityDate
        LastActivityDate = DateSerial(CInt(LastActivityYear), CInt(LastActivityMonth), CInt(LastActivityDay))
        LastActivityDate = DateAdd("h", CInt(LastActivityHour), LastActivityDate)
        LastActivityDate = DateAdd("n", CInt(LastActivityMinute), LastActivityDate)

        oKMSProduct.SetLastActivity LastActivityDate, LastActivityYear, LastActivityMonth, LastActivityDay, LastActivityHour, LastActivityMinute
    End If
     
  Set oAPI = MOMCreateObject("MOM.ScriptAPI")
  set oDiscoveryData = oAPI.CreateDiscoveryData(0, SourceId, ManagedEntityId)
  
  if KMSServiceSupportsApplicationTotalRequestsCount() = True Then
    Call UpdateProductInstanceUsingProductObject(oKMSProduct)
  Else
    if KMSServiceSupportsServiceTotalRequestsCount() = True Then
        Call UpdateProductInstanceUsingServiceObject(oKMSProduct)
    Else
    End If
  End If
  
  If IsNull(TotalRequests) Then
    Call oKMSProduct.SetLastActivityToCurrentTime
  Else
    If CLng(TotalRequests) &lt;&gt; oKMSProduct.TotalRequests Then
       Call oKMSProduct.SetLastActivityToCurrentTime
    Else
       Call oKMSProduct.CalculateIdleMinutes
    End If
  End If
  
  Call AddProductInstanceToDiscovery(oKMSProduct, oDiscoveryData)
  
  oAPI.Return(oDiscoveryData) 

End Sub
</ScriptBody>
                <TimeoutSeconds>$Config/TimeoutSeconds$</TimeoutSeconds>
              </DataSource>
            </MemberModules>
            <Composition>
              <Node ID="DU" />
            </Composition>
          </Composite>
        </ModuleImplementation>
        <OutputType>System!System.Discovery.Data</OutputType>
      </DataSourceModuleType>
    </ModuleTypes>
    <MonitorTypes>
      <UnitMonitorType ID="Microsoft.Windows.KeyManagement.Product.IdleMinute.ThresholdMonitorType" Accessibility="Public">
        <MonitorTypeStates>
          <MonitorTypeState ID="GreaterThanThreshold" />
          <MonitorTypeState ID="LessThanEqualThreshold" />
        </MonitorTypeStates>
        <Configuration>
          <xsd:element name="IntervalSeconds" type="xsd:integer" />
          <xsd:element name="IdleMinutes" type="xsd:string" />
          <xsd:element name="IdleMinutesThreshold" type="xsd:double" />
        </Configuration>
        <OverrideableParameters>
          <OverrideableParameter ID="IntervalSeconds" ParameterType="int" Selector="$Config/IntervalSeconds$" />
          <OverrideableParameter ID="IdleMinutesThreshold" ParameterType="int" Selector="$Config/IdleMinutesThreshold$" />
        </OverrideableParameters>
        <MonitorImplementation>
          <MemberModules>
            <DataSource ID="Scheduler" TypeID="System!System.Scheduler">
              <Scheduler>
                <SimpleReccuringSchedule>
                  <Interval Unit="Seconds">$Config/IntervalSeconds$</Interval>
                </SimpleReccuringSchedule>
                <ExcludeDates />
              </Scheduler>
            </DataSource>
            <ConditionDetection ID="FilterLessThanEqual" TypeID="System!System.ExpressionFilter">
              <Expression>
                <SimpleExpression>
                  <ValueExpression>
                    <Value Type="Double">$Config/IdleMinutes$</Value>
                  </ValueExpression>
                  <Operator>LessEqual</Operator>
                  <ValueExpression>
                    <Value Type="Double">$Config/IdleMinutesThreshold$</Value>
                  </ValueExpression>
                </SimpleExpression>
              </Expression>
            </ConditionDetection>
            <ConditionDetection ID="FilterGreaterThan" TypeID="System!System.ExpressionFilter">
              <Expression>
                <SimpleExpression>
                  <ValueExpression>
                    <Value Type="Double">$Config/IdleMinutes$</Value>
                  </ValueExpression>
                  <Operator>Greater</Operator>
                  <ValueExpression>
                    <Value Type="Double">$Config/IdleMinutesThreshold$</Value>
                  </ValueExpression>
                </SimpleExpression>
              </Expression>
            </ConditionDetection>
          </MemberModules>
          <RegularDetections>
            <RegularDetection MonitorTypeStateID="GreaterThanThreshold">
              <Node ID="FilterGreaterThan">
                <Node ID="Scheduler" />
              </Node>
            </RegularDetection>
            <RegularDetection MonitorTypeStateID="LessThanEqualThreshold">
              <Node ID="FilterLessThanEqual">
                <Node ID="Scheduler" />
              </Node>
            </RegularDetection>
          </RegularDetections>
        </MonitorImplementation>
      </UnitMonitorType>
      <UnitMonitorType ID="Microsoft.Windows.KeyManagement.Product.KMSCurrentCount.ThresholdMonitorType" Accessibility="Public">
        <MonitorTypeStates>
          <MonitorTypeState ID="GreaterThanEqualThreshold" />
          <MonitorTypeState ID="LessThanThreshold" />
        </MonitorTypeStates>
        <Configuration>
          <xsd:element name="IntervalSeconds" type="xsd:integer" />
          <xsd:element name="KMSCurrentCount" type="xsd:string" />
          <xsd:element name="KMSCurrentCountThreshold" type="xsd:double" />
        </Configuration>
        <OverrideableParameters>
          <OverrideableParameter ID="IntervalSeconds" ParameterType="int" Selector="$Config/IntervalSeconds$" />
          <OverrideableParameter ID="KMSCurrentCountThreshold" ParameterType="int" Selector="$Config/KMSCurrentCountThreshold$" />
        </OverrideableParameters>
        <MonitorImplementation>
          <MemberModules>
            <DataSource ID="Scheduler" TypeID="System!System.Scheduler">
              <Scheduler>
                <SimpleReccuringSchedule>
                  <Interval Unit="Seconds">$Config/IntervalSeconds$</Interval>
                </SimpleReccuringSchedule>
                <ExcludeDates />
              </Scheduler>
            </DataSource>
            <ConditionDetection ID="FilterLessThan" TypeID="System!System.ExpressionFilter">
              <Expression>
                <SimpleExpression>
                  <ValueExpression>
                    <Value Type="Double">$Config/KMSCurrentCount$</Value>
                  </ValueExpression>
                  <Operator>Less</Operator>
                  <ValueExpression>
                    <Value Type="Double">$Config/KMSCurrentCountThreshold$</Value>
                  </ValueExpression>
                </SimpleExpression>
              </Expression>
            </ConditionDetection>
            <ConditionDetection ID="FilterGreaterThanEqual" TypeID="System!System.ExpressionFilter">
              <Expression>
                <SimpleExpression>
                  <ValueExpression>
                    <Value Type="Double">$Config/KMSCurrentCount$</Value>
                  </ValueExpression>
                  <Operator>GreaterEqual</Operator>
                  <ValueExpression>
                    <Value Type="Double">$Config/KMSCurrentCountThreshold$</Value>
                  </ValueExpression>
                </SimpleExpression>
              </Expression>
            </ConditionDetection>
          </MemberModules>
          <RegularDetections>
            <RegularDetection MonitorTypeStateID="GreaterThanEqualThreshold">
              <Node ID="FilterGreaterThanEqual">
                <Node ID="Scheduler" />
              </Node>
            </RegularDetection>
            <RegularDetection MonitorTypeStateID="LessThanThreshold">
              <Node ID="FilterLessThan">
                <Node ID="Scheduler" />
              </Node>
            </RegularDetection>
          </RegularDetections>
        </MonitorImplementation>
      </UnitMonitorType>
    </MonitorTypes>
  </TypeDefinitions>
  <Monitoring>
    <Discoveries>
      <Discovery ID="Microsoft.Windows.KeyManagement.Service.Discovery" Enabled="true" Target="Windows!Microsoft.Windows.Computer" ConfirmDelivery="false" Remotable="true" Priority="Normal">
        <Category>Discovery</Category>
        <DiscoveryTypes>
          <DiscoveryClass TypeID="Microsoft.Windows.KeyManagement.Service">
            <Property PropertyID="ProcessID" />
            <Property PropertyID="ImageName" />
            <Property PropertyID="FilePath" />
            <Property PropertyID="ServiceName" />
            <Property PropertyID="ServiceState" />
            <Property PropertyID="KMSServiceVersion" />
            <Property PropertyID="KMSServicePath" />
            <Property TypeID="System!System.Entity" PropertyID="DisplayName" />
          </DiscoveryClass>
        </DiscoveryTypes>
        <DataSource ID="DS" TypeID="Microsoft.Windows.KeyManagement.Service.Discovery.DataSource">
          <IntervalSeconds>86400</IntervalSeconds>
          <SyncTime />
          <ComputerID>$Target/Property[Type="Windows!Microsoft.Windows.Computer"]/PrincipalName$</ComputerID>
          <ComputerName>$Target/Property[Type="Windows!Microsoft.Windows.Computer"]/NetworkName$</ComputerName>
          <TimeoutSeconds>300</TimeoutSeconds>
        </DataSource>
      </Discovery>
      <Discovery ID="Microsoft.Windows.KeyManagement.Product.Discovery" Enabled="true" Target="Microsoft.Windows.KeyManagement.Service" ConfirmDelivery="false" Remotable="true" Priority="Normal">
        <Category>Discovery</Category>
        <DiscoveryTypes>
          <DiscoveryClass TypeID="Microsoft.Windows.KeyManagement.Product">
            <Property TypeID="Microsoft.Windows.KeyManagement.Product" PropertyID="ProductSkuId" />
            <Property TypeID="Microsoft.Windows.KeyManagement.Product" PropertyID="ProductSkuName" />
            <Property TypeID="Microsoft.Windows.KeyManagement.Product" PropertyID="ProductSkuDescription" />
            <Property TypeID="Microsoft.Windows.KeyManagement.Product" PropertyID="KMSCurrentCount" />
            <Property TypeID="System!System.Entity" PropertyID="DisplayName" />
          </DiscoveryClass>
        </DiscoveryTypes>
        <DataSource ID="DS" TypeID="Microsoft.Windows.KeyManagement.Product.Discovery.DataSource">
          <IntervalSeconds>14400</IntervalSeconds>
          <SyncTime />
          <ComputerID>$Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/PrincipalName$</ComputerID>
          <ComputerName>$Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/NetworkName$</ComputerName>
          <ImageName>$Target/Property[Type="Microsoft.Windows.KeyManagement.Service"]/ImageName$</ImageName>
          <TimeoutSeconds>300</TimeoutSeconds>
        </DataSource>
      </Discovery>
      <Discovery ID="Microsoft.Windows.KeyManagement.Product.UpdateLastActivity" Enabled="true" Target="Microsoft.Windows.KeyManagement.Product" ConfirmDelivery="false" Remotable="true" Priority="Normal">
        <Category>Discovery</Category>
        <DiscoveryTypes>
          <DiscoveryClass TypeID="Microsoft.Windows.KeyManagement.Product">
            <Property TypeID="Microsoft.Windows.KeyManagement.Product" PropertyID="ProductSkuId" />
            <Property TypeID="Microsoft.Windows.KeyManagement.Product" PropertyID="KMSCurrentCount" />
            <Property TypeID="Microsoft.Windows.KeyManagement.Product" PropertyID="TotalRequests" />
            <Property TypeID="Microsoft.Windows.KeyManagement.Product" PropertyID="LastActivity" />
            <Property TypeID="Microsoft.Windows.KeyManagement.Product" PropertyID="LastActivityYear" />
            <Property TypeID="Microsoft.Windows.KeyManagement.Product" PropertyID="LastActivityMonth" />
            <Property TypeID="Microsoft.Windows.KeyManagement.Product" PropertyID="LastActivityDay" />
            <Property TypeID="Microsoft.Windows.KeyManagement.Product" PropertyID="LastActivityHour" />
            <Property TypeID="Microsoft.Windows.KeyManagement.Product" PropertyID="LastActivityMinute" />
            <Property TypeID="Microsoft.Windows.KeyManagement.Product" PropertyID="IdleMinutes" />
            <Property TypeID="System!System.Entity" PropertyID="DisplayName" />
          </DiscoveryClass>
        </DiscoveryTypes>
        <DataSource ID="DU" TypeID="Microsoft.Windows.KeyManagement.Product.UpdateLastActivity.Discovery.DataSource">
          <IntervalSeconds>3600</IntervalSeconds>
          <SyncTime />
          <ComputerID>$Target/Host/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/PrincipalName$</ComputerID>
          <ComputerName>$Target/Host/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/NetworkName$</ComputerName>
          <ImageName>$Target/Host/Property[Type="Microsoft.Windows.KeyManagement.Service"]/ImageName$</ImageName>
          <ProductSkuId>$Target/Property[Type="Microsoft.Windows.KeyManagement.Product"]/ProductSkuId$</ProductSkuId>
          <TotalRequests>$Target/Property[Type="Microsoft.Windows.KeyManagement.Product"]/TotalRequests$</TotalRequests>
          <LastActivityYear>$Target/Property[Type="Microsoft.Windows.KeyManagement.Product"]/LastActivityYear$</LastActivityYear>
          <LastActivityMonth>$Target/Property[Type="Microsoft.Windows.KeyManagement.Product"]/LastActivityMonth$</LastActivityMonth>
          <LastActivityDay>$Target/Property[Type="Microsoft.Windows.KeyManagement.Product"]/LastActivityDay$</LastActivityDay>
          <LastActivityHour>$Target/Property[Type="Microsoft.Windows.KeyManagement.Product"]/LastActivityHour$</LastActivityHour>
          <LastActivityMinute>$Target/Property[Type="Microsoft.Windows.KeyManagement.Product"]/LastActivityMinute$</LastActivityMinute>
          <TimeoutSeconds>300</TimeoutSeconds>
        </DataSource>
      </Discovery>
      <Discovery ID="Microsoft.Windows.KeyManagement.Service.ComputerGroupDiscovery" Target="Microsoft.Windows.KeyManagement.ComputerGroup" Enabled="true">
        <Category>Discovery</Category>
        <DiscoveryTypes>
          <DiscoveryRelationship TypeID="SC!Microsoft.SystemCenter.ComputerGroupContainsComputer" />
        </DiscoveryTypes>
        <DataSource ID="DiscoveryDataSource" TypeID="SC!Microsoft.SystemCenter.GroupPopulator">
          <RuleId>$MPElement$</RuleId>
          <GroupInstanceId>$Target/Id$</GroupInstanceId>
          <MembershipRules>
            <MembershipRule>
              <MonitoringClass>$MPElement[Name="Windows!Microsoft.Windows.Computer"]$</MonitoringClass>
              <RelationshipClass>$MPElement[Name="SC!Microsoft.SystemCenter.ComputerGroupContainsComputer"]$</RelationshipClass>
              <Expression>
                <Contains>
                  <MonitoringClass>$MPElement[Name="Microsoft.Windows.KeyManagement.Service"]$</MonitoringClass>
                </Contains>
              </Expression>
            </MembershipRule>
          </MembershipRules>
        </DataSource>
      </Discovery>
    </Discoveries>
    <Rules>
      <Rule ID="Microsoft.Windows.KeyManagement.Service.DNS_RR_publishing_failed" Enabled="true" Target="Microsoft.Windows.KeyManagement.Service" ConfirmDelivery="true" Remotable="true" Priority="Normal" DiscardLevel="100">
        <Category>EventCollection</Category>
        <DataSources>
          <DataSource ID="DS" TypeID="Windows!Microsoft.Windows.EventProvider">
            <ComputerName>$Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/NetworkName$</ComputerName>
            <LogName>Application</LogName>
            <Expression>
              <And>
                <Expression>
                  <SimpleExpression>
                    <ValueExpression>
                      <XPathQuery Type="UnsignedInteger">EventDisplayNumber</XPathQuery>
                    </ValueExpression>
                    <Operator>Equal</Operator>
                    <ValueExpression>
                      <Value Type="UnsignedInteger">12293</Value>
                    </ValueExpression>
                  </SimpleExpression>
                </Expression>
                <Expression>
                  <Or>
                    <Expression>
                      <SimpleExpression>
                        <ValueExpression>
                          <XPathQuery Type="String">PublisherName</XPathQuery>
                        </ValueExpression>
                        <Operator>Equal</Operator>
                        <ValueExpression>
                          <Value Type="String">Software Licensing Service</Value>
                        </ValueExpression>
                      </SimpleExpression>
                    </Expression>
                    <Expression>
                      <SimpleExpression>
                        <ValueExpression>
                          <XPathQuery Type="String">PublisherName</XPathQuery>
                        </ValueExpression>
                        <Operator>Equal</Operator>
                        <ValueExpression>
                          <Value Type="String">Microsoft-Windows-Security-Licensing-SLC</Value>
                        </ValueExpression>
                      </SimpleExpression>
                    </Expression>
                  </Or>
                </Expression>
              </And>
            </Expression>
          </DataSource>
        </DataSources>
        <WriteActions>
          <WriteAction ID="WriteToDB" TypeID="SC!Microsoft.SystemCenter.CollectEvent" />
        </WriteActions>
      </Rule>
      <Rule ID="Microsoft.Windows.KeyManagement.Service.KMS_initialization_failure" Enabled="true" Target="Microsoft.Windows.KeyManagement.Service" ConfirmDelivery="true" Remotable="true" Priority="Normal" DiscardLevel="100">
        <Category>EventCollection</Category>
        <DataSources>
          <DataSource ID="DS" TypeID="Windows!Microsoft.Windows.EventProvider">
            <ComputerName>$Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/NetworkName$</ComputerName>
            <LogName>Application</LogName>
            <Expression>
              <And>
                <Expression>
                  <SimpleExpression>
                    <ValueExpression>
                      <XPathQuery Type="UnsignedInteger">EventDisplayNumber</XPathQuery>
                    </ValueExpression>
                    <Operator>Equal</Operator>
                    <ValueExpression>
                      <Value Type="UnsignedInteger">12291</Value>
                    </ValueExpression>
                  </SimpleExpression>
                </Expression>
                <Expression>
                  <Or>
                    <Expression>
                      <SimpleExpression>
                        <ValueExpression>
                          <XPathQuery Type="String">PublisherName</XPathQuery>
                        </ValueExpression>
                        <Operator>Equal</Operator>
                        <ValueExpression>
                          <Value Type="String">Software Licensing Service</Value>
                        </ValueExpression>
                      </SimpleExpression>
                    </Expression>
                    <Expression>
                      <SimpleExpression>
                        <ValueExpression>
                          <XPathQuery Type="String">PublisherName</XPathQuery>
                        </ValueExpression>
                        <Operator>Equal</Operator>
                        <ValueExpression>
                          <Value Type="String">Microsoft-Windows-Security-Licensing-SLC</Value>
                        </ValueExpression>
                      </SimpleExpression>
                    </Expression>
                  </Or>
                </Expression>
              </And>
            </Expression>
          </DataSource>
        </DataSources>
        <WriteActions>
          <WriteAction ID="WriteToDB" TypeID="SC!Microsoft.SystemCenter.CollectEvent" />
        </WriteActions>
      </Rule>
    </Rules>
    <Tasks>
      <Task ID="Microsoft.Windows.KeyManagement.Service.StartService" Accessibility="Public" Enabled="true" Target="Microsoft.Windows.KeyManagement.Service" Timeout="300" Remotable="true">
        <Category>Maintenance</Category>
        <WriteAction ID="WA" TypeID="System!System.CommandExecuter">
          <ApplicationName>%SystemRoot%\System32\net.exe</ApplicationName>
          <WorkingDirectory>%SYSTEMROOT%\temp</WorkingDirectory>
          <CommandLine>start $Target/Property[Type="Microsoft.Windows.KeyManagement.Service"]/ImageName$</CommandLine>
          <TimeoutSeconds>60</TimeoutSeconds>
          <RequireOutput>true</RequireOutput>
          <Files />
        </WriteAction>
      </Task>
      <Task ID="Microsoft.Windows.KeyManagement.Service.StopService" Accessibility="Public" Enabled="true" Target="Microsoft.Windows.KeyManagement.Service" Timeout="300" Remotable="true">
        <Category>Maintenance</Category>
        <WriteAction ID="WA" TypeID="System!System.CommandExecuter">
          <ApplicationName>%SystemRoot%\System32\net.exe</ApplicationName>
          <WorkingDirectory>%SYSTEMROOT%\temp</WorkingDirectory>
          <CommandLine>stop $Target/Property[Type="Microsoft.Windows.KeyManagement.Service"]/ImageName$</CommandLine>
          <TimeoutSeconds>60</TimeoutSeconds>
          <RequireOutput>true</RequireOutput>
          <Files />
        </WriteAction>
      </Task>
      <Task ID="Microsoft.Windows.KeyManagement.Service.LicenseState" Accessibility="Public" Enabled="true" Target="Microsoft.Windows.KeyManagement.Service" Timeout="300" Remotable="true">
        <Category>Maintenance</Category>
        <WriteAction ID="WA" TypeID="System!System.CommandExecuter">
          <ApplicationName />
          <WorkingDirectory />
          <CommandLine>%SystemRoot%\System32\cscript %SystemRoot%\System32\slmgr.vbs /dli</CommandLine>
          <TimeoutSeconds>180</TimeoutSeconds>
          <RequireOutput>true</RequireOutput>
          <Files />
        </WriteAction>
      </Task>
    </Tasks>
    <Monitors>
      <UnitMonitor ID="Microsoft.Windows.KeyManagement.Service.Check" Accessibility="Public" Enabled="true" Target="Microsoft.Windows.KeyManagement.Service" ParentMonitorID="Health!System.Health.AvailabilityState" Remotable="false" Priority="Normal" TypeID="Windows!Microsoft.Windows.CheckNTServiceStateMonitorType" ConfirmDelivery="false">
        <Category>Custom</Category>
        <AlertSettings AlertMessage="Microsoft.Windows.KeyManagement.Service.Check.AlertMessage">
          <AlertOnState>Error</AlertOnState>
          <AutoResolve>true</AutoResolve>
          <AlertPriority>Normal</AlertPriority>
          <AlertSeverity>Error</AlertSeverity>
        </AlertSettings>
        <OperationalStates>
          <OperationalState ID="Error" MonitorTypeStateID="NotRunning" HealthState="Error" />
          <OperationalState ID="Success" MonitorTypeStateID="Running" HealthState="Success" />
        </OperationalStates>
        <Configuration>
          <ComputerName>$Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/NetworkName$</ComputerName>
          <ServiceName>$Target/Property[Type="Microsoft.Windows.KeyManagement.Service"]/ImageName$</ServiceName>
        </Configuration>
      </UnitMonitor>
      <UnitMonitor ID="Microsoft.Windows.KeyManagement.Service.InitFailure" Accessibility="Public" Enabled="true" Target="Microsoft.Windows.KeyManagement.Service" ParentMonitorID="Health!System.Health.AvailabilityState" Remotable="true" Priority="Normal" TypeID="Windows!Microsoft.Windows.SingleEventLogManualReset2StateMonitorType" ConfirmDelivery="true">
        <Category>AvailabilityHealth</Category>
        <AlertSettings AlertMessage="Microsoft.Windows.KeyManagement.Service.InitFailure_AlertMessageResourceID">
          <AlertOnState>Error</AlertOnState>
          <AutoResolve>true</AutoResolve>
          <AlertPriority>Normal</AlertPriority>
          <AlertSeverity>Error</AlertSeverity>
        </AlertSettings>
        <OperationalStates>
          <OperationalState ID="EventRaised" MonitorTypeStateID="EventRaised" HealthState="Error" />
          <OperationalState ID="ManualResetEventRaised" MonitorTypeStateID="ManualResetEventRaised" HealthState="Success" />
        </OperationalStates>
        <Configuration>
          <ComputerName>$Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/NetworkName$</ComputerName>
          <LogName>Application</LogName>
          <Expression>
            <And>
              <Expression>
                <SimpleExpression>
                  <ValueExpression>
                    <XPathQuery Type="UnsignedInteger">EventDisplayNumber</XPathQuery>
                  </ValueExpression>
                  <Operator>Equal</Operator>
                  <ValueExpression>
                    <Value Type="UnsignedInteger">12291</Value>
                  </ValueExpression>
                </SimpleExpression>
              </Expression>
              <Expression>
                <Or>
                  <Expression>
                    <SimpleExpression>
                      <ValueExpression>
                        <XPathQuery Type="String">PublisherName</XPathQuery>
                      </ValueExpression>
                      <Operator>Equal</Operator>
                      <ValueExpression>
                        <Value Type="String">Software Licensing Service</Value>
                      </ValueExpression>
                    </SimpleExpression>
                  </Expression>
                  <Expression>
                    <SimpleExpression>
                      <ValueExpression>
                        <XPathQuery Type="String">PublisherName</XPathQuery>
                      </ValueExpression>
                      <Operator>Equal</Operator>
                      <ValueExpression>
                        <Value Type="String">Microsoft-Windows-Security-Licensing-SLC</Value>
                      </ValueExpression>
                    </SimpleExpression>
                  </Expression>
                </Or>
              </Expression>
            </And>
          </Expression>
        </Configuration>
      </UnitMonitor>
      <UnitMonitor ID="Microsoft.Windows.KeyManagement.Service.RenewalTimerFailure" Accessibility="Public" Enabled="true" Target="Microsoft.Windows.KeyManagement.Service" ParentMonitorID="Health!System.Health.AvailabilityState" Remotable="true" Priority="Normal" TypeID="Windows!Microsoft.Windows.SingleEventLogManualReset2StateMonitorType" ConfirmDelivery="true">
        <Category>AvailabilityHealth</Category>
        <AlertSettings AlertMessage="Microsoft.Windows.KeyManagement.Service.RenewalTimerFailure_AlertMessageResourceID">
          <AlertOnState>Error</AlertOnState>
          <AutoResolve>true</AutoResolve>
          <AlertPriority>Normal</AlertPriority>
          <AlertSeverity>Error</AlertSeverity>
        </AlertSettings>
        <OperationalStates>
          <OperationalState ID="EventRaised" MonitorTypeStateID="EventRaised" HealthState="Error" />
          <OperationalState ID="ManualResetEventRaised" MonitorTypeStateID="ManualResetEventRaised" HealthState="Success" />
        </OperationalStates>
        <Configuration>
          <ComputerName>$Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/NetworkName$</ComputerName>
          <LogName>Application</LogName>
          <Expression>
            <And>
              <Expression>
                <SimpleExpression>
                  <ValueExpression>
                    <XPathQuery Type="UnsignedInteger">EventDisplayNumber</XPathQuery>
                  </ValueExpression>
                  <Operator>Equal</Operator>
                  <ValueExpression>
                    <Value Type="UnsignedInteger">12292</Value>
                  </ValueExpression>
                </SimpleExpression>
              </Expression>
              <Expression>
                <Or>
                  <Expression>
                    <SimpleExpression>
                      <ValueExpression>
                        <XPathQuery Type="String">PublisherName</XPathQuery>
                      </ValueExpression>
                      <Operator>Equal</Operator>
                      <ValueExpression>
                        <Value Type="String">Software Licensing Service</Value>
                      </ValueExpression>
                    </SimpleExpression>
                  </Expression>
                  <Expression>
                    <SimpleExpression>
                      <ValueExpression>
                        <XPathQuery Type="String">PublisherName</XPathQuery>
                      </ValueExpression>
                      <Operator>Equal</Operator>
                      <ValueExpression>
                        <Value Type="String">Microsoft-Windows-Security-Licensing-SLC</Value>
                      </ValueExpression>
                    </SimpleExpression>
                  </Expression>
                </Or>
              </Expression>
            </And>
          </Expression>
        </Configuration>
      </UnitMonitor>
      <UnitMonitor ID="Microsoft.Windows.KeyManagement.Service.DNS_Publishing_Monitor" Accessibility="Public" Enabled="true" Target="Microsoft.Windows.KeyManagement.Service" ParentMonitorID="Health!System.Health.AvailabilityState" Remotable="true" Priority="Normal" TypeID="Windows!Microsoft.Windows.2SingleEventLog2StateMonitorType" ConfirmDelivery="false">
        <Category>AvailabilityHealth</Category>
        <AlertSettings AlertMessage="Microsoft.Windows.KeyManagement.Service.DNS_Publishing_Monitor.AlertMessage">
          <AlertOnState>Error</AlertOnState>
          <AutoResolve>true</AutoResolve>
          <AlertPriority>Normal</AlertPriority>
          <AlertSeverity>Error</AlertSeverity>
        </AlertSettings>
        <OperationalStates>
          <OperationalState ID="DNSProblem" MonitorTypeStateID="FirstEventRaised" HealthState="Error" />
          <OperationalState ID="DNSOK" MonitorTypeStateID="SecondEventRaised" HealthState="Success" />
        </OperationalStates>
        <Configuration>
          <FirstComputerName>$Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/PrincipalName$</FirstComputerName>
          <FirstLogName>Application</FirstLogName>
          <FirstExpression>
            <And>
              <Expression>
                <SimpleExpression>
                  <ValueExpression>
                    <XPathQuery>EventDisplayNumber</XPathQuery>
                  </ValueExpression>
                  <Operator>Equal</Operator>
                  <ValueExpression>
                    <Value>12293</Value>
                  </ValueExpression>
                </SimpleExpression>
              </Expression>
              <Expression>
                <Or>
                  <Expression>
                    <SimpleExpression>
                      <ValueExpression>
                        <XPathQuery Type="String">PublisherName</XPathQuery>
                      </ValueExpression>
                      <Operator>Equal</Operator>
                      <ValueExpression>
                        <Value Type="String">Software Licensing Service</Value>
                      </ValueExpression>
                    </SimpleExpression>
                  </Expression>
                  <Expression>
                    <SimpleExpression>
                      <ValueExpression>
                        <XPathQuery Type="String">PublisherName</XPathQuery>
                      </ValueExpression>
                      <Operator>Equal</Operator>
                      <ValueExpression>
                        <Value Type="String">Microsoft-Windows-Security-Licensing-SLC</Value>
                      </ValueExpression>
                    </SimpleExpression>
                  </Expression>
                </Or>
              </Expression>
            </And>
          </FirstExpression>
          <SecondComputerName>$Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/PrincipalName$</SecondComputerName>
          <SecondLogName>Application</SecondLogName>
          <SecondExpression>
            <And>
              <Expression>
                <SimpleExpression>
                  <ValueExpression>
                    <XPathQuery>EventDisplayNumber</XPathQuery>
                  </ValueExpression>
                  <Operator>Equal</Operator>
                  <ValueExpression>
                    <Value>12294</Value>
                  </ValueExpression>
                </SimpleExpression>
              </Expression>
              <Expression>
                <Or>
                  <Expression>
                    <SimpleExpression>
                      <ValueExpression>
                        <XPathQuery Type="String">PublisherName</XPathQuery>
                      </ValueExpression>
                      <Operator>Equal</Operator>
                      <ValueExpression>
                        <Value Type="String">Software Licensing Service</Value>
                      </ValueExpression>
                    </SimpleExpression>
                  </Expression>
                  <Expression>
                    <SimpleExpression>
                      <ValueExpression>
                        <XPathQuery Type="String">PublisherName</XPathQuery>
                      </ValueExpression>
                      <Operator>Equal</Operator>
                      <ValueExpression>
                        <Value Type="String">Microsoft-Windows-Security-Licensing-SLC</Value>
                      </ValueExpression>
                    </SimpleExpression>
                  </Expression>
                </Or>
              </Expression>
            </And>
          </SecondExpression>
        </Configuration>
      </UnitMonitor>
      <UnitMonitor ID="Microsoft.Windows.KeyManagement.Product.LowCountMonitor" Target="Microsoft.Windows.KeyManagement.Product" TypeID="Microsoft.Windows.KeyManagement.Product.KMSCurrentCount.ThresholdMonitorType" Enabled="true" Remotable="false" ParentMonitorID="Health!System.Health.AvailabilityState" Accessibility="Public">
        <Category>AvailabilityHealth</Category>
        <AlertSettings AlertMessage="Microsoft.Windows.KeyManagement.Product.LowCountMonitor_AlertMessageResourceID">
          <AlertOnState>Warning</AlertOnState>
          <AutoResolve>true</AutoResolve>
          <AlertPriority>Normal</AlertPriority>
          <AlertSeverity>Information</AlertSeverity>
        </AlertSettings>
        <OperationalStates>
          <OperationalState HealthState="Success" MonitorTypeStateID="GreaterThanEqualThreshold" ID="OverThreshold" />
          <OperationalState HealthState="Warning" MonitorTypeStateID="LessThanThreshold" ID="UnderThreshold" />
        </OperationalStates>
        <Configuration>
          <IntervalSeconds>900</IntervalSeconds>
          <KMSCurrentCount>$Target/Property[Type="Microsoft.Windows.KeyManagement.Product"]/KMSCurrentCount$</KMSCurrentCount>
          <KMSCurrentCountThreshold>5</KMSCurrentCountThreshold>
        </Configuration>
      </UnitMonitor>
      <UnitMonitor ID="Microsoft.Windows.KeyManagement.Product.IdleMinutesMonitor" Target="Microsoft.Windows.KeyManagement.Product" TypeID="Microsoft.Windows.KeyManagement.Product.IdleMinute.ThresholdMonitorType" Enabled="true" Remotable="false" ParentMonitorID="Health!System.Health.PerformanceState" Accessibility="Public">
        <Category>PerformanceHealth</Category>
        <AlertSettings AlertMessage="Microsoft.Windows.KeyManagement.Product.IdleMinutesMonitor_AlertMessageResourceID">
          <AlertOnState>Error</AlertOnState>
          <AutoResolve>true</AutoResolve>
          <AlertPriority>Normal</AlertPriority>
        </AlertSettings>
        <OperationalStates>
          <OperationalState HealthState="Success" MonitorTypeStateID="LessThanEqualThreshold" ID="UnderThreshold" />
          <OperationalState HealthState="Error" MonitorTypeStateID="GreaterThanThreshold" ID="OverThreshold" />
        </OperationalStates>
        <Configuration>
          <IntervalSeconds>900</IntervalSeconds>
          <IdleMinutes>$Target/Property[Type="Microsoft.Windows.KeyManagement.Product"]/IdleMinutes$</IdleMinutes>
          <IdleMinutesThreshold>480</IdleMinutesThreshold>
        </Configuration>
      </UnitMonitor>
      <DependencyMonitor ID="Microsoft.Windows.KeyManagement.Service.ProductAvailabilityRollup" Accessibility="Public" Enabled="true" Target="Microsoft.Windows.KeyManagement.Service" ParentMonitorID="Health!System.Health.AvailabilityState" Remotable="true" Priority="Normal" RelationshipType="Microsoft.Windows.KeyManagement.ServiceHostsProduct" MemberMonitor="Health!System.Health.AvailabilityState">
        <Category>AvailabilityHealth</Category>
        <Algorithm>WorstOf</Algorithm>
        <MemberUnAvailable>Error</MemberUnAvailable>
      </DependencyMonitor>
      <DependencyMonitor ID="Microsoft.Windows.KeyManagement.Service.ProductPerformanceRollup" Accessibility="Public" Enabled="true" Target="Microsoft.Windows.KeyManagement.Service" ParentMonitorID="Health!System.Health.PerformanceState" Remotable="true" Priority="Normal" RelationshipType="Microsoft.Windows.KeyManagement.ServiceHostsProduct" MemberMonitor="Health!System.Health.PerformanceState">
        <Category>PerformanceHealth</Category>
        <Algorithm>WorstOf</Algorithm>
        <MemberUnAvailable>Error</MemberUnAvailable>
      </DependencyMonitor>
    </Monitors>
  </Monitoring>
  <Presentation>
    <Views>
      <View ID="Microsoft.Windows.KeyManagement.Service.Alerts" Accessibility="Public" Enabled="true" Target="Microsoft.Windows.KeyManagement.Service" TypeID="SC!Microsoft.SystemCenter.AlertViewType" Visible="true">
        <Category>Operations</Category>
        <Criteria>
          <ResolutionState>
            <StateRange Operator="NotEquals">255</StateRange>
          </ResolutionState>
        </Criteria>
      </View>
      <View ID="Microsoft.Windows.KeyManagement.Product.Alerts" Accessibility="Public" Enabled="true" Target="Microsoft.Windows.KeyManagement.Product" TypeID="SC!Microsoft.SystemCenter.AlertViewType" Visible="true">
        <Category>Operations</Category>
        <Criteria>
          <ResolutionState>
            <StateRange Operator="NotEquals">255</StateRange>
          </ResolutionState>
        </Criteria>
      </View>
      <View ID="Microsoft.Windows.KeyManagement.Service.StateView" Accessibility="Public" Enabled="true" Target="Microsoft.Windows.KeyManagement.Service" TypeID="SC!Microsoft.SystemCenter.StateViewType" Visible="true">
        <Category>Operations</Category>
        <Criteria />
        <Presentation>
          <ColumnInfo Index="0" SortIndex="-1" Width="100" Grouped="false" Sorted="true" IsSortable="true" Visible="true" SortOrder="Ascending">
            <Name>State</Name>
            <Id>Microsoft.Windows.KeyManagement.Service</Id>
          </ColumnInfo>
          <ColumnInfo Index="1" SortIndex="-1" Width="22" Grouped="false" Sorted="false" IsSortable="true" Visible="true" SortOrder="Ascending">
            <Name>Maintenance Mode</Name>
            <Id>InMaintenanceMode</Id>
          </ColumnInfo>
          <ColumnInfo Index="2" SortIndex="-1" Width="150" Grouped="false" Sorted="false" IsSortable="true" Visible="true" SortOrder="Ascending">
            <Name>Host</Name>
            <Id>Path</Id>
          </ColumnInfo>
          <ColumnInfo Index="3" SortIndex="-1" Width="80" Grouped="false" Sorted="false" IsSortable="true" Visible="true" SortOrder="Ascending">
            <Name>Image Name</Name>
            <Id>ImageName</Id>
          </ColumnInfo>
          <ColumnInfo Index="4" SortIndex="-1" Width="100" Grouped="false" Sorted="false" IsSortable="true" Visible="true" SortOrder="Ascending">
            <Name>Version</Name>
            <Id>KMSServiceVersion</Id>
          </ColumnInfo>
          <ColumnInfo Index="5" SortIndex="-1" Width="200" Grouped="false" Sorted="false" IsSortable="true" Visible="true" SortOrder="Ascending">
            <Name>Windows Service Name</Name>
            <Id>ServiceName</Id>
          </ColumnInfo>
          <ColumnInfo Index="6" SortIndex="-1" Width="200" Grouped="false" Sorted="false" IsSortable="true" Visible="true" SortOrder="Ascending">
            <Name>File Path</Name>
            <Id>FilePath</Id>
          </ColumnInfo>
        </Presentation>
      </View>
      <View ID="Microsoft.Windows.KeyManagement.Product.StateView" Accessibility="Public" Enabled="true" Target="Microsoft.Windows.KeyManagement.Product" TypeID="SC!Microsoft.SystemCenter.StateViewType" Visible="true">
        <Category>Operations</Category>
        <Criteria />
        <Presentation>
          <ColumnInfo Index="0" SortIndex="-1" Width="100" Grouped="false" Sorted="true" IsSortable="true" Visible="true" SortOrder="Ascending">
            <Name>State</Name>
            <Id>Microsoft.Windows.KeyManagement.Product</Id>
          </ColumnInfo>
          <ColumnInfo Index="1" SortIndex="-1" Width="22" Grouped="false" Sorted="false" IsSortable="true" Visible="true" SortOrder="Ascending">
            <Name>Maintenance Mode</Name>
            <Id>InMaintenanceMode</Id>
          </ColumnInfo>
          <ColumnInfo Index="2" SortIndex="-1" Width="150" Grouped="false" Sorted="false" IsSortable="true" Visible="true" SortOrder="Ascending">
            <Name>Host</Name>
            <Id>Path</Id>
          </ColumnInfo>
          <ColumnInfo Index="2" SortIndex="-1" Width="150" Grouped="false" Sorted="false" IsSortable="true" Visible="true" SortOrder="Ascending">
            <Name>Sku Id</Name>
            <Id>ProductSkuId</Id>
          </ColumnInfo>
          <ColumnInfo Index="3" SortIndex="-1" Width="80" Grouped="false" Sorted="false" IsSortable="true" Visible="true" SortOrder="Ascending">
            <Name>Sku Name</Name>
            <Id>ProductSkuName</Id>
          </ColumnInfo>
          <ColumnInfo Index="4" SortIndex="-1" Width="100" Grouped="false" Sorted="false" IsSortable="true" Visible="true" SortOrder="Ascending">
            <Name>ProductSkuDescription</Name>
            <Id>ProductSkuDescription</Id>
          </ColumnInfo>
          <ColumnInfo Index="5" SortIndex="-1" Width="200" Grouped="false" Sorted="false" IsSortable="true" Visible="true" SortOrder="Ascending">
            <Name>Current Count</Name>
            <Id>KMSCurrentCount</Id>
          </ColumnInfo>
          <ColumnInfo Index="5" SortIndex="-1" Width="200" Grouped="false" Sorted="false" IsSortable="true" Visible="true" SortOrder="Ascending">
            <Name>Last Activity</Name>
            <Id>LastActivity</Id>
          </ColumnInfo>
          <ColumnInfo Index="5" SortIndex="-1" Width="200" Grouped="false" Sorted="false" IsSortable="true" Visible="true" SortOrder="Ascending">
            <Name>Idle Minutes</Name>
            <Id>IdleMinutes</Id>
          </ColumnInfo>
          <ColumnInfo Index="5" SortIndex="-1" Width="200" Grouped="false" Sorted="false" IsSortable="true" Visible="true" SortOrder="Ascending">
            <Name>Total Requests</Name>
            <Id>TotalRequests</Id>
          </ColumnInfo>
        </Presentation>
      </View>
      <View ID="Microsoft.Windows.KeyManagement.Service.StateDetailsView" Accessibility="Public" Enabled="true" Target="Microsoft.Windows.KeyManagement.Service" TypeID="SC!Microsoft.SystemCenter.StateDetailDefinitionViewType" Visible="true">
        <Category>Operations</Category>
        <Monitors>
          <Monitor>$MPElement[Name="Health!System.Health.AvailabilityState"]$</Monitor>
          <Monitor>$MPElement[Name="Health!System.Health.PerformanceState"]$</Monitor>
        </Monitors>
      </View>
      <View ID="Microsoft.Windows.KeyManagement.Product.StateDetailsView" Accessibility="Public" Enabled="true" Target="Microsoft.Windows.KeyManagement.Product" TypeID="SC!Microsoft.SystemCenter.StateDetailDefinitionViewType" Visible="true">
        <Category>Operations</Category>
        <Monitors>
          <Monitor>$MPElement[Name="Health!System.Health.AvailabilityState"]$</Monitor>
          <Monitor>$MPElement[Name="Health!System.Health.PerformanceState"]$</Monitor>
        </Monitors>
      </View>
      <View ID="Microsoft.Windows.KeyManagement.Service.TaskStatusView" Accessibility="Public" Enabled="true" Target="Microsoft.Windows.KeyManagement.Service" TypeID="SC!Microsoft.SystemCenter.TaskStatusViewType" Visible="true">
        <Category>Operations</Category>
      </View>
    </Views>
    <Folders>
      <Folder ID="Microsoft.Windows.KeyManagement.Service.ViewFolder.Root" Accessibility="Public" ParentFolder="SC!Microsoft.SystemCenter.Monitoring.ViewFolder.Root" />
      <Folder ID="Microsoft.Windows.KeyManagement.Product.ViewFolder.Root" Accessibility="Public" ParentFolder="Microsoft.Windows.KeyManagement.Service.ViewFolder.Root" />
    </Folders>
    <FolderItems>
      <FolderItem ElementID="Microsoft.Windows.KeyManagement.Service.StateView" Folder="Microsoft.Windows.KeyManagement.Service.ViewFolder.Root" />
      <FolderItem ElementID="Microsoft.Windows.KeyManagement.Service.Alerts" Folder="Microsoft.Windows.KeyManagement.Service.ViewFolder.Root" />
      <FolderItem ElementID="Microsoft.Windows.KeyManagement.Service.TaskStatusView" Folder="Microsoft.Windows.KeyManagement.Service.ViewFolder.Root" />
      <FolderItem ElementID="Microsoft.Windows.KeyManagement.Product.StateView" Folder="Microsoft.Windows.KeyManagement.Product.ViewFolder.Root" />
      <FolderItem ElementID="Microsoft.Windows.KeyManagement.Product.Alerts" Folder="Microsoft.Windows.KeyManagement.Product.ViewFolder.Root" />
    </FolderItems>
    <StringResources>
      <StringResource ID="Microsoft.Windows.KeyManagement.Service.InitFailure_AlertMessageResourceID" />
      <StringResource ID="Microsoft.Windows.KeyManagement.Service.RenewalTimerFailure_AlertMessageResourceID" />
      <StringResource ID="Microsoft.Windows.KeyManagement.Product.LowCountMonitor_AlertMessageResourceID" />
      <StringResource ID="Microsoft.Windows.KeyManagement.Product.IdleMinutesMonitor_AlertMessageResourceID" />
      <StringResource ID="Microsoft.Windows.KeyManagement.Service.DNS_Publishing_Monitor.AlertMessage" />
      <StringResource ID="Microsoft.Windows.KeyManagement.Service.Check.AlertMessage" />
    </StringResources>
  </Presentation>
  <LanguagePacks>
    <LanguagePack ID="ENU" IsDefault="true">
      <DisplayStrings>
        <DisplayString ElementID="Microsoft.Windows.KeyManagementService">
          <Name>Key Management Service</Name>
          <Description>Microsoft Key Management Service Management Pack. This management pack discovers and monitors Microsoft Key Management Service that is part of Volume Activation 2.0 used to support centrally managed Volume License keys.  

Note:  If you are using Key Management Service management pack version 6.0.6278.9, you will need to delete that before you can import this management pack. This management pack is not upgrade compatible with the previous version.

Note:  When uninstalling the previous Key Management Service Management Pack, if reporting was enabled an additional step is necessary.  The Data Warehouse should be purged of event data associated with the KMS reports.

Steps:
1.  Open SQL Query Analyzer and select the OperationsManagerDW database
2.  Open the uninstall.sql file attached with this management pack
3.  Execute (F5)
</Description>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Service">
          <Name>Key Management Service</Name>
          <Description>Instances of Key Management Service</Description>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Service" SubElementID="ProcessID">
          <Name>PID</Name>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Service" SubElementID="ImageName">
          <Name>Image Name</Name>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Service" SubElementID="FilePath">
          <Name>File Path</Name>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Service" SubElementID="ServiceName">
          <Name>Service Name</Name>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Service" SubElementID="ServiceState">
          <Name>Service State</Name>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Service" SubElementID="KMSServiceVersion">
          <Name>KMS Version</Name>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Service" SubElementID="KMSServicePath">
          <Name>KMS Service Path</Name>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Product">
          <Name>Key Management Service Product</Name>
          <Description>Instances of Key Management Service Product</Description>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Product" SubElementID="ProductSkuId">
          <Name>SKU Id</Name>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Product" SubElementID="ProductSkuName">
          <Name>Name</Name>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Product" SubElementID="ProductSkuDescription">
          <Name>Description</Name>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Product" SubElementID="KMSCurrentCount">
          <Name>KMS Current Count</Name>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Product" SubElementID="LastActivity">
          <Name>Last Activity</Name>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Product" SubElementID="LastActivityYear">
          <Name>Last Activity(Year)</Name>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Product" SubElementID="LastActivityMonth">
          <Name>Last Activity(Month)</Name>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Product" SubElementID="LastActivityDay">
          <Name>Last Activity(Day)</Name>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Product" SubElementID="LastActivityHour">
          <Name>Last Activity(Hour)</Name>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Product" SubElementID="LastActivityMinute">
          <Name>Last Activity(Minute)</Name>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Product" SubElementID="IdleMinutes">
          <Name>IdleMinutes</Name>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Product" SubElementID="TotalRequests">
          <Name>Total Requests</Name>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Service.Discovery">
          <Name>KeyManagement Service Discovery</Name>
          <Description>This object discovery discovers Key Management Service which is implemented as sppsvc.exe (Microsoft Windows 2003 Server or Microsoft Windows 2008 Server R2) or slsvc.exe (Microsoft Windows 2008 Server or Microsoft Windows Vista)</Description>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Product.Discovery">
          <Name>KeyManagement Service Product Discovery</Name>
          <Description>This object discovery discovers Key Management Service Products which are hosted by the Key Management Service.</Description>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Product.UpdateLastActivity">
          <Name>KeyManagement Service Product Discovery (Update LastActivity and IdleMinutes)</Name>
          <Description>This object discovery updates the LastActivty and IdleMinute properties of Key Management Service Products which are hosted by the Key Management Service.</Description>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Product.IdleMinute.ThresholdMonitorType" SubElementID="IntervalSeconds">
          <Name>Frequency in seconds</Name>
          <Description>The frequency in seconds for monitoring KMS Product Idle Minutes against threshold.</Description>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Product.IdleMinute.ThresholdMonitorType" SubElementID="IdleMinutesThreshold">
          <Name>Threshold (Minutes)</Name>
          <Description>The threshold in minutes for idle activity.</Description>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Product.KMSCurrentCount.ThresholdMonitorType" SubElementID="IntervalSeconds">
          <Name>Frequency in seconds</Name>
          <Description>The frequency in seconds for monitoring KMS Current Count against a threshold.</Description>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Product.KMSCurrentCount.ThresholdMonitorType" SubElementID="KMSCurrentCountThreshold">
          <Name>Threshold (KMS Current Count)</Name>
          <Description>The threshold used to determine if a KMS has the required KMS Current Count.</Description>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Service.Discovery.DataSource">
          <Name>Key Management Service Discovery Module</Name>
          <Description>The module responsible for Key Management Service discovery.</Description>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Service.Discovery.DataSource" SubElementID="IntervalSeconds">
          <Name>Frequency in seconds</Name>
          <Description>The frequency in seconds for running discovery for the Key Management Service.</Description>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Service.Discovery.DataSource" SubElementID="TimeoutSeconds">
          <Name>Timeout in seconds</Name>
          <Description>Timeout for the Key Management Service discovery module.</Description>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Product.Discovery.DataSource">
          <Name>Key Management Service Product Discovery Module</Name>
          <Description>The module responsible for discovery of a product using Key Management Service.</Description>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Product.Discovery.DataSource" SubElementID="IntervalSeconds">
          <Name>Frequency in seconds</Name>
          <Description>The frequency in seconds for running discovery for a product using Key Management Service.</Description>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Product.Discovery.DataSource" SubElementID="TimeoutSeconds">
          <Name>Timeout in seconds</Name>
          <Description>Timeout for the Key Management Service Product discovery module.</Description>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Product.UpdateLastActivity.Discovery.DataSource">
          <Name>Key Management Service Product Last Activity Discovery Module</Name>
          <Description>The module responsible for updating the last activity value for a Key Management Service product.</Description>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Product.UpdateLastActivity.Discovery.DataSource" SubElementID="IntervalSeconds">
          <Name>Frequency in seconds</Name>
          <Description>The frequency in seconds for running discovery for updating the last activity value.</Description>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Product.UpdateLastActivity.Discovery.DataSource" SubElementID="TimeoutSeconds">
          <Name>Timeout in seconds</Name>
          <Description>Timeout for the Key Management Service Product discovery module.</Description>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.ServiceHostsProduct">
          <Name>Key Management Service hosts Key Management Product</Name>
          <Description>Key Management Service hosts one or more products.</Description>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Product.IdleMinute.ThresholdMonitorType">
          <Name>KMS Product Idle Minute Threshold Monitor Type</Name>
          <Description>The monitor type for monitoring Idle Minutes against a maximum threshold value.</Description>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Product.KMSCurrentCount.ThresholdMonitorType">
          <Name>KMSCurrentCount Threshold Monitor Type</Name>
          <Description>The monitor type for monitoring KMSCurrentCount against a minimum threshold value.</Description>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Service.InitFailure">
          <Name>Initialization Failure</Name>
          <Description>KMS initialization failure</Description>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Service.InitFailure_AlertMessageResourceID">
          <Name>InitializationFailure</Name>
          <Description>Volume-licensed client was unable to initialize the Key Management Service</Description>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Service.InitFailure" SubElementID="ManualResetEventRaised">
          <Name>Initialization OK</Name>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Service.InitFailure" SubElementID="EventRaised">
          <Name>Initialization Failed</Name>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Service.RenewalTimerFailure">
          <Name>Renewal Timer Failure</Name>
          <Description>Key Management Service (KMS) failed to initialize renewal timer</Description>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Service.RenewalTimerFailure_AlertMessageResourceID">
          <Name>Renewal Timer Failure</Name>
          <Description>Key Management Service (KMS) failed to initialize renewal timer</Description>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Service.RenewalTimerFailure" SubElementID="ManualResetEventRaised">
          <Name>Manual Reset Event Raised</Name>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Service.RenewalTimerFailure" SubElementID="EventRaised">
          <Name>Event Raised</Name>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Product.LowCountMonitor_AlertMessageResourceID">
          <Name>KMS Low Activation Count</Name>
          <Description>
        •	The KMS machine count is less than the limit required by this rule.
        •	The limit defined in this rule is not the same as the minimum count required to sustain activations (which can differ by Windows edition).
      </Description>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Product.IdleMinutesMonitor_AlertMessageResourceID">
          <Name>Idle Minutes Monitor Alert</Name>
          <Description>Key Management Service (KMS) inactivity exceeded threshold.</Description>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Service.DNS_Publishing_Monitor.AlertMessage">
          <Name>DNS Publishing Monitor</Name>
          <Description>DNS RR publishing failed</Description>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Service.DNS_Publishing_Monitor">
          <Name>DNS Publishing Monitor</Name>
          <Description>DNS RR publishing failed</Description>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Service.Alerts">
          <Name>Alerts</Name>
          <Description>KMS Alerts</Description>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Service.StateView">
          <Name>State</Name>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Service.StateDetailsView">
          <Name>State Details</Name>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Service.TaskStatusView">
          <Name>Task Status</Name>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Service.ViewFolder.Root">
          <Name>Key Management Service</Name>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Product.LowCountMonitor">
          <Name>KMS Low Activation Count</Name>
          <Description>The KMS machine count is less than the limit required by this rule.</Description>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Product.LowCountMonitor" SubElementID="OverThreshold">
          <Name>Over Threshold</Name>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Product.LowCountMonitor" SubElementID="UnderThreshold">
          <Name>Under Threshold</Name>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Product.IdleMinutesMonitor">
          <Name>KMS Idle Time Monitor</Name>
          <Description>The purpose of this rule is to alert system administrators to a possible KMS or network outage. This rule monitors the end-to-end operation of KMS activation. A notification event is created by KMS if no activation or renewal requests were logged by KMS (activity event 12290) in the specified time interval. In addition to new activations, periodic renewal requests are expected to occur (default is 7 days). Whether or not this alert is serious depends on the number of machines in the KMS environment, how many are actually connected, and the configured renewal interval.</Description>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Product.IdleMinutesMonitor" SubElementID="OverThreshold">
          <Name>Over Threshold</Name>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Product.IdleMinutesMonitor" SubElementID="UnderThreshold">
          <Name>Under Threshold</Name>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Service.Check.AlertMessage">
          <Name>Key Management Service is not running</Name>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Service.Check">
          <Name>KMS Windows Service</Name>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Service.DNS_Publishing_Monitor" SubElementID="DNSOK">
          <Name>DNS publishing succeeded</Name>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Service.DNS_Publishing_Monitor" SubElementID="DNSProblem">
          <Name>DNS publishing failed</Name>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Service.DNS_RR_publishing_failed">
          <Name>DNS RR publishing failed Event Collection Rule</Name>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Service.KMS_initialization_failure">
          <Name>KMS initialization failure collection rule</Name>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Service.Check" SubElementID="Success">
          <Name>Service running</Name>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Service.Check" SubElementID="Error">
          <Name>Service not running</Name>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Service.StartService">
          <Name>KMS Start Service</Name>
          <Description>It starts Key Management Service : slsvc.exe on VISTA or Windows 2008 Server or sppsvc.exe on Windows 2003 Server</Description>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Service.StopService">
          <Name>KMS Stop Service</Name>
          <Description>It stops Key Management Service : slsvc.exe on VISTA or Windows 2008 Server or sppsvc.exe on Windows 2003 Server</Description>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Service.LicenseState">
          <Name>KMS License State</Name>
          <Description>It displays the current license state of Key Management Service. It runs following command :  cscript %SystemRoot%\System32\slmgr.vbs /dli</Description>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.ComputerGroup">
          <Name>Key Management Service Computers</Name>
          <Description>A group containing all Windows computers that are running Key Management Service</Description>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Service.ComputerGroupDiscovery">
          <Name>Discover Key Management Service Computer Group membership</Name>
          <Description>Populates the computer group to contains all computers running Key Management Service</Description>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Product.Alerts">
          <Name>Alerts</Name>
          <Description>KMS Product Alerts</Description>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Product.StateView">
          <Name>State</Name>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Product.StateDetailsView">
          <Name>State Details</Name>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Product.ViewFolder.Root">
          <Name>Key Management Service Products</Name>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Service.ProductAvailabilityRollup">
          <Name>Key Management Service Product Availability Rollup</Name>
        </DisplayString>
        <DisplayString ElementID="Microsoft.Windows.KeyManagement.Service.ProductPerformanceRollup">
          <Name>Key Management Service Product Performance Rollup</Name>
        </DisplayString>
      </DisplayStrings>
      <KnowledgeArticles>
        <KnowledgeArticle ElementID="Microsoft.Windows.KeyManagement.Service.DNS_Publishing_Monitor" Visible="true">
          <MamlContent>
            <maml:section xmlns:maml="http://schemas.microsoft.com/maml/2004/10">
              <maml:title>Summary</maml:title>
              <maml:para>KMS was unable to publish a DNS record. Whether this is a serious issue or not depends on the abilities and configuration of the Domain Name System at your facility.</maml:para>
            </maml:section>
            <maml:section xmlns:maml="http://schemas.microsoft.com/maml/2004/10">
              <maml:title>Causes</maml:title>
              <maml:para>Possible causes include:</maml:para>
              <maml:para>DNS does not support SRV records or dynamic publishing (DDNS).</maml:para>
              <maml:para>The KMS machine does not have permission to update DNS.</maml:para>
              <maml:para>The designated DNS domain does not exist or is unreachable.</maml:para>
            </maml:section>
            <maml:section xmlns:maml="http://schemas.microsoft.com/maml/2004/10">
              <maml:title>Resolutions</maml:title>
              <maml:para>If your DNS configuration or policies do not permit dynamic SRV publishing, you should disable publishing by using slmgr.vbs -cdns. Verify that the target domain is correct and accessible. If you have specified publishing to multiple domains, verify that the value specified in the registry (DnsDomainPublishList) is correct.</maml:para>
            </maml:section>
          </MamlContent>
        </KnowledgeArticle>
        <KnowledgeArticle ElementID="Microsoft.Windows.KeyManagement.Service.RenewalTimerFailure" Visible="true">
          <MamlContent>
            <maml:section xmlns:maml="http://schemas.microsoft.com/maml/2004/10">
              <maml:title>Summary</maml:title>
              <maml:para>The KMS client was unable to initialize the renewal timer as provided by the KMS machine.</maml:para>
            </maml:section>
            <maml:section xmlns:maml="http://schemas.microsoft.com/maml/2004/10">
              <maml:title>Causes</maml:title>
              <maml:para>Operating system corruption or software licensing service (slsvc.exe or sppsvc.exe) failure.</maml:para>
            </maml:section>
            <maml:section xmlns:maml="http://schemas.microsoft.com/maml/2004/10">
              <maml:title>Resolutions</maml:title>
              <maml:para>Repair or reinstall the operating system or its configuration Contact Microsoft Customer Support Services for further assistance.</maml:para>
            </maml:section>
            <maml:section xmlns:maml="http://schemas.microsoft.com/maml/2004/10">
              <maml:title>Additional</maml:title>
              <maml:para>Sample Event </maml:para>
              <maml:para>Volume-licensed client was unable to initialize the Key Management Service renewal timer.%nInfo:%n%1 The parameter provides the error code.</maml:para>
            </maml:section>
          </MamlContent>
        </KnowledgeArticle>
        <KnowledgeArticle ElementID="Microsoft.Windows.KeyManagement.Product.LowCountMonitor" Visible="true">
          <MamlContent>
            <maml:section xmlns:maml="http://schemas.microsoft.com/maml/2004/10">
              <maml:title>Summary</maml:title>
              <maml:para>The KMS machine count is less than the limit required by this rule. The limit defined in this rule is not the same as the minimum count required to sustain activations (which can differ). This rule provides an early warning system of a potential problem. If the KMS count never reaches the required value for activation or drops below it, machines will be unable to activate with this KMS.</maml:para>
            </maml:section>
            <maml:section xmlns:maml="http://schemas.microsoft.com/maml/2004/10">
              <maml:title>Causes</maml:title>
              <maml:para>The number of incoming activations or renewals is not enough to sustain the required machine count.</maml:para>
            </maml:section>
            <maml:section xmlns:maml="http://schemas.microsoft.com/maml/2004/10">
              <maml:title>Resolutions</maml:title>
              <maml:para>Ensure that the total number of KMS clients is sufficient to satisfy at least the minimum required activation count for each KMS machine you have enabled. Ensure the Renewal Interval has not been set too high. This information is obtained by running slmgr.vbs -dli.</maml:para>
            </maml:section>
            <maml:section xmlns:maml="http://schemas.microsoft.com/maml/2004/10">
              <maml:title>Additional</maml:title>
              <maml:para>Note that this count is capped at twice the minimum threshold value for a specific product. This is to ensure that the volume-licensed systems are deployed in an enterprise network by requiring that a minimum number of systems check in periodically.</maml:para>
              <maml:para />
              <maml:para>You may want to change the threshold value used as the low-water mark. This value is defined in the Threshold property for this rule.</maml:para>
            </maml:section>
          </MamlContent>
        </KnowledgeArticle>
        <KnowledgeArticle ElementID="Microsoft.Windows.KeyManagement.Product.IdleMinutesMonitor" Visible="true">
          <MamlContent>
            <maml:section xmlns:maml="http://schemas.microsoft.com/maml/2004/10">
              <maml:title>Summary</maml:title>
              <maml:para>The purpose of this rule is to alert system administrators to a possible KMS or network outage. This rule monitors the end-to-end operation of KMS activation. A notification event is created by KMS if no activation or renewal requests were logged by KMS (activity event 12290) in the specified time interval. In addition to new activations, periodic renewal requests are expected to occur (default is 7 days). Whether or not this alert is serious depends on the number of machines in the KMS environment, how many are actually connected, and the configured renewal interval.</maml:para>
            </maml:section>
            <maml:section xmlns:maml="http://schemas.microsoft.com/maml/2004/10">
              <maml:title>Causes</maml:title>
              <maml:para>Any failure or incorrect configuration of the KMS service, other Windows components, firewall, hardware, network or routers can trigger the Idle Minutes Alert. This alert can also result from normal behavior, since it is possible that not enough machines attempted to activate or renew during the specified time interval.</maml:para>
            </maml:section>
            <maml:section xmlns:maml="http://schemas.microsoft.com/maml/2004/10">
              <maml:title>Resolutions</maml:title>
              <maml:para>The first step is to determine whether there really is a problem. Start with a known good KMS client and run (with elevated privileges) the script slmgr.vbs -ato . If the activation/renewal fails, it will report an error code. You can direct the client to connect to a specific KMS machine by using the slmgr.vbs -skms option. The request event (12288) and response event (12289) in the Windows Application event log may provide additional information, including the identity of failing KMS machines. If there has been a failure, check the following:</maml:para>
              <maml:para>Software Licensing service (slsvc) is running.</maml:para>
              <maml:para>Other KMS machine behavior is normal.</maml:para>
              <maml:para />
              <maml:para>KMS firewall port is open (default is TCP 1688).</maml:para>
              <maml:para />
              <maml:para>Attempt to connect to KMS using telnet to the KMS port(you won’t be able to do anything other than connect)</maml:para>
              <maml:para>Use a network monitor (e.g. netmon) to capture and trace network problems.</maml:para>
              <maml:para />
              <maml:para>There is one Idle Minutes Monitor that is used to monitor for activity. It may be desirable to adjust the time threshold, depending on expected KMS activity. </maml:para>
              <maml:para />
              <maml:para />
            </maml:section>
            <maml:section xmlns:maml="http://schemas.microsoft.com/maml/2004/10">
              <maml:title>Additional</maml:title>
              <maml:para>There are 3 Missing Activation Requests rules that collectively span a 24-hour period. It may be desirable to disable one or more of these and/or to adjust the time intervals, depending on expected KMS activity.</maml:para>
            </maml:section>
          </MamlContent>
        </KnowledgeArticle>
        <KnowledgeArticle ElementID="Microsoft.Windows.KeyManagement.Service.InitFailure" Visible="true">
          <MamlContent>
            <maml:section xmlns:maml="http://schemas.microsoft.com/maml/2004/10">
              <maml:title>Summary</maml:title>
              <maml:para>The KMS client was unable to initialize the licensing service.</maml:para>
            </maml:section>
            <maml:section xmlns:maml="http://schemas.microsoft.com/maml/2004/10">
              <maml:title>Causes</maml:title>
              <maml:para>Operating system corruption or software licensing service (slsvc.exe or sppsvc.exe) failure.</maml:para>
            </maml:section>
            <maml:section xmlns:maml="http://schemas.microsoft.com/maml/2004/10">
              <maml:title>Resolutions</maml:title>
              <maml:para>Repair or reinstall the operating system or its configuration Contact Microsoft Customer Support Services for further assistance.</maml:para>
            </maml:section>
          </MamlContent>
        </KnowledgeArticle>
        <KnowledgeArticle ElementID="Microsoft.Windows.KeyManagement.Service.Discovery" Visible="true">
          <MamlContent>
            <maml:section xmlns:maml="http://schemas.microsoft.com/maml/2004/10">
              <maml:title>Summary</maml:title>
              <maml:para>This object discovery discovers Key Management Service which is implemented as sppsvc.exe on Microsoft Windows 2003 Server or slsvc.exe on Microsoft Windows 2008 Server or Microsoft Windows Vista</maml:para>
            </maml:section>
            <maml:section xmlns:maml="http://schemas.microsoft.com/maml/2004/10">
              <maml:title>Configuration</maml:title>
              <maml:para>Only activated instance of Key Management Service is discovered. The service can be activated online using following script :</maml:para>
              <maml:para />
              <maml:para>cscript C:\windows\system32\slmgr.vbs /ato</maml:para>
              <maml:para />
              <maml:para>or it can be activated offline using obtained volume key as follows :</maml:para>
              <maml:para />
              <maml:para>cscript C:\windows\system32\slmgr.vbs /ipk &lt;KMS Key&gt;</maml:para>
              <maml:para />
              <maml:para>If no error was reported, the KMS host is now ready to be used by KMS clients for activation. Additional configuration is optional and will usually not be required. You can confirm your KMS license state and settings by running:cscript C:\windows\system32\slmgr.vbs /dli</maml:para>
              <maml:para />
            </maml:section>
          </MamlContent>
        </KnowledgeArticle>
        <KnowledgeArticle ElementID="Microsoft.Windows.KeyManagement.Service.Check" Visible="true">
          <MamlContent>
            <maml:section xmlns:maml="http://schemas.microsoft.com/maml/2004/10">
              <maml:title>Summary</maml:title>
              <maml:para>This monitor uses Windows Win32 to check the status of the Key Management  Service and generates an alert when the service is set to start automatically and is not running.</maml:para>
            </maml:section>
            <maml:section xmlns:maml="http://schemas.microsoft.com/maml/2004/10">
              <maml:title>Causes</maml:title>
              <maml:para>A service can stop for many reasons, including:</maml:para>
              <maml:para />
              <maml:list>
                <maml:listItem>
                  <maml:para>The service was stopped by an administrator</maml:para>
                </maml:listItem>
                <maml:listItem>
                  <maml:para>The service was prevented from starting because the user account could not be authenticated.</maml:para>
                </maml:listItem>
                <maml:listItem>
                  <maml:para>The service encountered an exception that stopped the service.</maml:para>
                </maml:listItem>
                <maml:listItem>
                  <maml:para>The service was improperly configured, which prevented it from starting </maml:para>
                </maml:listItem>
              </maml:list>
              <maml:para />
            </maml:section>
            <maml:section xmlns:maml="http://schemas.microsoft.com/maml/2004/10">
              <maml:title>Resolutions</maml:title>
              <maml:para>You can attempt to restart the service</maml:para>
            </maml:section>
          </MamlContent>
        </KnowledgeArticle>
        <KnowledgeArticle ElementID="Microsoft.Windows.KeyManagementService" Visible="true">
          <MamlContent>
            <maml:section xmlns:maml="http://schemas.microsoft.com/maml/2004/10">
              <maml:title>Summary</maml:title>
              <maml:para>The Key Management Service (KMS) is one of two licensing options made available in Microsoft Volume Activation 2.0. The KMS is used to activate Windows Vista™ and Windows Server 2008 computers. Each activation request is logged on the KMS host. The KMS Management Pack collects data from the event logs of defined KMS hosts, and monitors those hosts for availability. This provides visibility into the activation traffic and the license status of VA clients on the network.</maml:para>
            </maml:section>
            <maml:section xmlns:maml="http://schemas.microsoft.com/maml/2004/10">
              <maml:title>External</maml:title>
              <maml:para>http://www.microsoft.com/licensing/resources/vol/default.mspx</maml:para>
            </maml:section>
          </MamlContent>
        </KnowledgeArticle>
        <KnowledgeArticle ElementID="Microsoft.Windows.KeyManagement.Service.ProductAvailabilityRollup" Visible="true">
          <MamlContent>
            <maml:section xmlns:maml="http://schemas.microsoft.com/maml/2004/10">
              <maml:title>Summary</maml:title>
              <maml:para>The overall Availability Health State of Products hosted by a Service aggregates to the Service.</maml:para>
            </maml:section>
          </MamlContent>
        </KnowledgeArticle>
        <KnowledgeArticle ElementID="Microsoft.Windows.KeyManagement.Service.ProductPerformanceRollup" Visible="true">
          <MamlContent>
            <maml:section xmlns:maml="http://schemas.microsoft.com/maml/2004/10">
              <maml:title>Summary</maml:title>
              <maml:para>The overall Performance Health State of Products hosted by a Service aggregates to the Service.</maml:para>
            </maml:section>
          </MamlContent>
        </KnowledgeArticle>
        <KnowledgeArticle ElementID="Microsoft.Windows.KeyManagement.Service.DNS_RR_publishing_failed" Visible="true">
          <MamlContent>
            <maml:section xmlns:maml="http://schemas.microsoft.com/maml/2004/10">
              <maml:title>Summary</maml:title>
              <maml:para>KMS was unable to publish a DNS record. Whether this is a serious issue or not depends on the abilities and configuration of the Domain Name System at your facility.</maml:para>
            </maml:section>
            <maml:section xmlns:maml="http://schemas.microsoft.com/maml/2004/10">
              <maml:title>Configuration</maml:title>
              <maml:para>.</maml:para>
            </maml:section>
            <maml:section xmlns:maml="http://schemas.microsoft.com/maml/2004/10">
              <maml:title>Causes</maml:title>
              <maml:para>Possible causes include:</maml:para>
              <maml:para>DNS does not support SRV records or dynamic publishing (DDNS).</maml:para>
              <maml:para>The KMS machine does not have permission to update DNS.</maml:para>
              <maml:para>The designated DNS domain does not exist or is unreachable.</maml:para>
              <maml:para />
            </maml:section>
            <maml:section xmlns:maml="http://schemas.microsoft.com/maml/2004/10">
              <maml:title>Resolutions</maml:title>
              <maml:para>If your DNS configuration or policies do not permit dynamic SRV publishing, you should disable publishing by using slmgr.vbs -cdns. Verify that the target domain is correct and accessible. If you have specified publishing to multiple domains, verify that the value specified in the registry (DnsDomainPublishList) is correct.</maml:para>
            </maml:section>
          </MamlContent>
        </KnowledgeArticle>
        <KnowledgeArticle ElementID="Microsoft.Windows.KeyManagement.Service.KMS_initialization_failure" Visible="true">
          <MamlContent>
            <maml:section xmlns:maml="http://schemas.microsoft.com/maml/2004/10">
              <maml:title>Summary</maml:title>
              <maml:para>The KMS client was unable to initialize the software licensing service.</maml:para>
            </maml:section>
            <maml:section xmlns:maml="http://schemas.microsoft.com/maml/2004/10">
              <maml:title>Causes</maml:title>
              <maml:para>Operating system corruption or software licensing service (slsvc.exe or sppsvc.exe) failure.</maml:para>
            </maml:section>
            <maml:section xmlns:maml="http://schemas.microsoft.com/maml/2004/10">
              <maml:title>Resolutions</maml:title>
              <maml:para>Repair or reinstall the operating system or its configuration Contact Microsoft Customer Support Services for further assistance.</maml:para>
            </maml:section>
          </MamlContent>
        </KnowledgeArticle>
      </KnowledgeArticles>
    </LanguagePack>
  </LanguagePacks>
</ManagementPack>