The frequency in seconds for running discovery for updating the last activity value.
SyncTime
string
$Config/SyncTime$
TimeoutSeconds
int
$Config/TimeoutSeconds$
Timeout in seconds
Timeout for the Key Management Service Product discovery module.
Source Code:
<DataSourceModuleType ID="Microsoft.KMS.Product.UpdateLastActivity.Discovery.DS" Accessibility="Public" Batching="false">
<Configuration>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="IntervalSeconds" type="xsd:integer"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="SyncTime" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="ComputerID" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="ComputerName" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="ImageName" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="ProductSkuId" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="TotalRequests" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="LastActivityYear" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="LastActivityMonth" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="LastActivityDay" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="LastActivityHour" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="LastActivityMinute" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" 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>Microsoft.KMS.Product.UpdateLastActivity.Discovery.DS.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><Script>
' 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 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
'
' 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 <> 0 Then ThrowScriptError "Unable to create automation object '" & sProgramId & "'", 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 & ". " & 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 '" & sNamespace
ThrowScriptErrorNoAbort "Unable to open WMI Namespace '" & sNamespace & "'. 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 <> 0 Then
ThrowScriptError "The Query '" & sQuery & "' 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 '" & sNamespace
ThrowScriptErrorNoAbort "Unable to open WMI Namespace '" & sNamespace & "'. 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 <> 0 Then
ThrowScriptError "The Query '" & sQuery & "' 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 <> 0 Then
ThrowScriptError "The Query '" & sQuery & "' 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 <> 0 Then
ThrowScriptError "The Query '" & sQuery & "' 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 <> 0 Then
IsValidWMIExecQuery = False
Else
IsValidWMIExecQuery = True
End If
Function UpdateProductInstanceUsingProductObject(ByRef oKMSProduct)
Dim sNamespace
sNamespace = "winmgmts://" & TargetComputer & "/root/cimv2"
Dim oKMSProducts
Dim oProduct
Dim KMSTotalRequests
Dim KMSCurrentCount
Set oKMSProducts = WMIExecQuery(sNamespace, "SELECT ID, KeyManagementServiceTotalRequests, KeyManagementServiceCurrentCount FROM SoftwareLicensingProduct WHERE ID = '" & ProductSkuId & "'")
if oKMSProducts.Count <> 1 Then
UpdateProductInstanceUsingProductObject = False
Exit Function
Else
For Each oProduct in oKMSProducts
KMSTotalRequests = oProduct.KeyManagementServiceTotalRequests
KMSCurrentCount = oProduct.KeyManagementServiceCurrentCount
Next
End If
Function UpdateProductInstanceUsingServiceObject(ByRef oKMSProduct)
Dim sNamespace
sNamespace = "winmgmts://" & TargetComputer & "/root/cimv2"
Dim oKMSServices
Dim oService
Dim KMSTotalRequests
Dim KMSCurrentCount
Set oKMSServices = WMIExecQuery(sNamespace, "SELECT KeyManagementServiceTotalRequests, KeyManagementServiceCurrentCount FROM SoftwareLicensingService")
if oKMSServices.Count <> 1 Then
UpdateProductInstanceUsingServiceObject = False
Exit Function
Else
For Each oService in oKMSServices
KMSTotalRequests = oService.KeyManagementServiceTotalRequests
KMSCurrentCount = oService.KeyManagementServiceCurrentCount
Next
End If
Dim oAPI
Set oAPI = MOMCreateObject("MOM.ScriptAPI")
Call oAPI.LogScriptEvent("Microsoft.KMS.Product.UpdateLastActivity.Discovery.DS.vbs", 4100, 0, "Starting discovery script.")
Dim oArgs
Set oArgs = WScript.Arguments
if oArgs.Count < 4 Then
Call oAPI.LogScriptEvent("Microsoft.KMS.Product.UpdateLastActivity.Discovery.DS.vbs", 4100, 0, "LogScriptEvent script was called with fewer than 4 arguments and was not executed.")
Wscript.Quit -1
End If
if oArgs.Count > 6 Then
TotalRequests = oArgs(6)
if (Trim(TotalRequests) = "") Then
TotalRequests = null
End If
Else
TotalRequests = null
End If
if oArgs.Count > 7 Then
If oArgs.Count <> 12 Then
Call oAPI.LogScriptEvent("Microsoft.KMS.Product.UpdateLastActivity.Discovery.DS.vbs", 4100, 0, "LogScriptEvent script was called no having the expected 12 arguments and was not executed.")
Wscript.Quit -1
End If
Dim KMSVer
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 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) <> oKMSProduct.TotalRequests Then
Call oKMSProduct.SetLastActivityToCurrentTime
Else
Call oKMSProduct.CalculateIdleMinutes
End If
End If