Lenovo Blade OOB Heathy Reflection Discovery Provider

IBM.BladeOOBHeathyReflection.DiscoveryProvider (DataSourceModuleType)

Element properties:

TypeDataSourceModuleType
IsolationAny
AccessibilityPublic
RunAsDefault
OutputTypeSystem.Discovery.Data

Member Modules:

ID Module Type TypeId RunAs 
DS DataSource Microsoft.Windows.TimedScript.DiscoveryProvider Default

Overrideable Parameters:

IDParameterTypeSelectorDisplay NameDescription
IntervalSecondsint$Config/IntervalSeconds$Lenovo Blade OOB Heathy Reflection Discovery Provider IntervalLenovo Blade OOB Heathy Reflection Discovery ProviderInterval Seconds
TimeoutSecondsint$Config/TimeoutSeconds$Lenovo Blade OOB Heathy Reflection Discovery Provider TimeoutLenovo Blade OOB Heathy Reflection Discovery Provider Timeout Seconds

Source Code:

<DataSourceModuleType ID="IBM.BladeOOBHeathyReflection.DiscoveryProvider" Accessibility="Public">
<Configuration>
<xsd:element name="IntervalSeconds" type="xsd:integer"/>
<xsd:element name="TimeoutSeconds" type="xsd:integer"/>
<!--<xsd:element name="IsDetected" type="xsd:string" />-->
</Configuration>
<OverrideableParameters>
<OverrideableParameter ID="IntervalSeconds" ParameterType="int" Selector="$Config/IntervalSeconds$"/>
<OverrideableParameter ID="TimeoutSeconds" ParameterType="int" Selector="$Config/TimeoutSeconds$"/>
</OverrideableParameters>
<ModuleImplementation Isolation="Any">
<Composite>
<MemberModules>
<DataSource ID="DS" TypeID="Windows!Microsoft.Windows.TimedScript.DiscoveryProvider">
<IntervalSeconds>$Config/IntervalSeconds$</IntervalSeconds>
<SyncTime/>
<ScriptName>IBMBladeOOBHeathyReflectionDiscovery.vbs</ScriptName>
<Arguments>"$MPElement$" "$Target/Id$"</Arguments>
<ScriptBody><Script>

SetLocale("en-us")

Const IBMHWMP_LICENSE_KEY = "Software\IBM\Systems Management Integrations\License"
Const LenovoHWMP_LICENSE_KEY = "Software\Lenovo\Systems Management Integrations\License"
'Const IBMHWMP_LICENSE_SETUP_VERSION ="Version" 'suppose it is 3.0.6, the license tool's version, I saw the server side and endpoint is different, so this is useless.
Const IBMHWMP_LICENSE_TOKEN_NAME = "v1-0002.A"
Const IBMHWMP_LICENSE_LEVEL = "Level" 'suppose it is 3.0 or it is useless if we could get the Level from the token.
Dim oArgs
Set oArgs = WScript.Arguments
Dim sourceID, managedEntityID
Dim IBName,BCCIP,OOBName,isDetected
Dim description

sourceID = "$MPElement$"
managedEntityID = "$Target/Id$"


BCCIP = "$Target/Property[Type='IBMBCC!IBM.BladeCenter']/PrimaryMMIPAddress$"

Dim display


'description = display + "-" +BCCIP

Const HKEY_LOCAL_MACHINE = &amp;H80000002
Const DEBUG_INFO_KEY = "SOFTWARE\Lenovo\Lenovo SCOM MP\Debug"
Const DEBUG_LEVEL_NAME = "Level"

Dim oBag, oReg, RC_Code, debug
debug = -1
Set oAPI = CreateObject("MOM.ScriptAPI")
Set oReg = GetObject("winmgmts://localhost/root/default:StdRegProv")
If (not(oReg is nothing)) Then
RC_Code = oReg.GetStringValue(HKEY_LOCAL_MACHINE, DEBUG_INFO_KEY, DEBUG_LEVEL_NAME, debug)
If(RC_Code &lt;&gt;0) Then
debug = -1
End If
End If
Call LogDebugString("Entering IBMBladeOOBHeathyReflectionDiscovery " + vbCrLf + sourceID + vbCrLf +managedEntityID , INFO_LEVEL)
Dim list, licenseLevel, licenseToken
Set oDiscoveryData = oAPI.CreateDiscoveryData(0, sourceID, managedEntityID)

'Lin If no license, we just do not create the Reflection object.
'Check the server whether has a license
'same method with GetLicenseLevel(licenseLevel, licenseToken) in IBMLicenseServerDiscovery.vbs
'If no license then
'Call oAPI.Return(oDiscoveryData) 'create an empty return data and quit WScript

Dim SCOMServer,blade

Set SCOMServer = WScript.CreateObject("IBM.SystemsManagement.SCOMHelper.SCOMServer")

Call SCOMServer.InitSCOMServerConnection()

isDetected = SCOMServer.GetIBDetected(BCCIP)
dim index
index =0

for each item in isDetected
if (StrComp(item, "true", 1) = 0) then
set blade= SCOMServer.GetBladeRelationInfor(index)
if (not(blade is nothing)) then
description = blade.OOBBladeName + "-"+ blade.MMIPAddress
'WSCript.echo blade.OOBBladeName + " " + blade.blade.MMIPAddress+ " " + blade.OOBBladeBay + " " + blade.IBHostName + " "+blade.IBDetected
call CreateHealthReflectionObject(description, blade.IBHostName,BCCIP,blade.OOBBladeBay,blade.OOBBladeName)
end if
end if
index = index +1
next

Call oAPI.Return(oDiscoveryData)
Call LogDebugString("Create Health Reflection Object completed.", INFO_LEVEL)

Function CreateHealthReflectionObject(description, hostID,ip,bay, oobName)
Dim oInst
Set oInst = oDiscoveryData.CreateClassInstance("$MPElement[Name='IBM.SystemX.BladeOOBHeathyReflection']$")
Call oInst.AddProperty("$MPElement[Name='IBM.SystemX.BladeOOBHeathyReflection']/Name$", description)
Call oInst.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", "OOB-IB Blade Info")
Call oInst.AddProperty("$MPElement[Name='IBM.SystemX.BladeOOBHeathyReflection']/BladeCenterIPAddress$", ip)
Call oInst.AddProperty("$MPElement[Name='IBM.SystemX.BladeOOBHeathyReflection']/BladeCenterBladeName$", description)
Call oInst.AddProperty("$MPElement[Name='IBM.SystemX.BladeOOBHeathyReflection']/IBName$", hostID)
Call oInst.AddProperty("$MPElement[Name='IBM.SystemX.BladeOOBHeathyReflection']/IBDetected$", "true")
'set the relationship with IBM.BladeCenter.BladeModule
'Call oInst.AddProperty("$MPElement[Name='IBMBCC!IBM.BladeCenter.Module']/ModuleBay$", bay)
'set the host relationship
Call oInst.AddProperty("$MPElement[Name='IBMxSystems!IBM.SystemX.Platform']/HostPrincipalName$", hostID)
Call oInst.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", hostID)
oDiscoveryData.AddInstance(oInst)
'{{{
'[Lin]Do not add the reference relationship, it will cause the repeate create blade instance. MOMScriptAPI do not support the update data.
'Dim oRelRef, oSourceInst
'Set oSourceInst = oDiscoveryData.CreateClassInstance("$MPElement[Name='IBMBCC!IBM.BladeCenter.BladeModule']$")
'Call oSourceInst.AddProperty("$MPElement[Name='IBMBCC!IBM.BladeCenter.Module']/ModuleBay$", bay)
'Call oSourceInst.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", oobName)
'Set oRelRef = oDiscoveryData.CreateRelationshipInstance("$MPElement[Name='IBM.Relation.SystemX.OOBBladeVsOOBHeathyReflection']$")
'oRelRef.Source = oSourceInst
'oRelRef.Target = oInst
'Call oRelRef.AddProperty("$MPElement[Name='IBM.Relation.SystemX.OOBBladeVsOOBHeathyReflection']/Ipaddress$", ip)
'Call oDiscoveryData.AddInstance(oRelRef)
'}}}
Call LogDebugString("Add " + description +" Instance to DB", INFO_LEVEL)
End Function


Sub LogDebugString(debugString, debugLevel)

If (Int(debug) &gt;= Int(debugLevel)) Then
Call oAPI.LogScriptEvent("IBMBladeOOBHeathyReflectionDiscovery.vbs", 301, debugLevel, debugString)
End If

End Sub

Function GetLicenseLevel(ByRef sLicLevel, ByRef sLicTok)

sLicLevel = null
sLicTok = null
If IsEmpty(oReg) Or IsNull(oReg) Then
Exit Function
End If

Dim oLicValidator, aLicLevelERs, oBestLevelER
Set oLicValidator = new LicManager
Call oLicValidator.LoadFromRegistry()
aLicLevelERs = oLicValidator.LevelERs
If IsArray(aLicLevelERs) Then
sLicTok = oLicValidator.LicenseToken
Call oLicValidator.FindBestFeatLevel(oBestLevelER)
If Not IsNull(oBestLevelER) Then
sLicLevel = oBestLevelER.ToString()
Else
Call LogDebugString("The best matched feature level could " + _
"not be obtained on this IBM License Server", WARNING_LEVEL)
End If
Else
Call LogDebugString("No feature levels activated on this IBM License Server", WARNING_LEVEL)
End If

End Function

class LicManager

private m_aLevelERs
public property get LevelERs
LevelERs = m_aLevelERs
end property

private m_sLicToken
public property get LicenseToken
LicenseToken = m_sLicToken
end property

private sub Class_Initialize()
m_aLevelERs = null
m_sLicToken = ""
end sub

public sub LoadFromRegistry()

dim nLevelsLoaded, licenseFlag
nLevelsLoaded = 0
m_aLevelERs = null
m_sLicToken = ""
licenseFlag = 1

dim aKeyEntryNames, aKeyEntryTypes
Call LogDebugString(".. LicManager: loading from registry key '" + _
LenovoHWMP_LICENSE_KEY + "'", INFO_LEVEL_FUNCTION)
Call oReg.EnumValues( HKEY_LOCAL_MACHINE, LenovoHWMP_LICENSE_KEY, _
aKeyEntryNames, aKeyEntryTypes )

if isNull( aKeyEntryNames ) or not(isArray( aKeyEntryNames )) then
Call LogDebugString(".. LicManager: loading from registry key '" + _
IBMHWMP_LICENSE_KEY + "'", INFO_LEVEL_FUNCTION)
Call oReg.EnumValues( HKEY_LOCAL_MACHINE, IBMHWMP_LICENSE_KEY, _
aKeyEntryNames, aKeyEntryTypes )
licenseFlag = 0
end if

if isNull( aKeyEntryNames ) or not(isArray( aKeyEntryNames )) then
exit sub
end if

Call LogDebugString(".. LicManager: # of registry value entries = " + _
CStr(UBound(aKeyEntryNames)+1), INFO_LEVEL_DETAIL)

dim ii
for ii=0 to UBound(aKeyEntryNames)
if 1 = aKeyEntryTypes( ii ) then ' 1 = REG_SZ
if IBMHWMP_LICENSE_TOKEN_NAME = aKeyEntryNames(ii) then
dim sLevelERsEncoded, sLevelERsDecoded, asSplitERs
if licenseFlag = 1 then
call oReg.GetStringValue( HKEY_LOCAL_MACHINE, LenovoHWMP_LICENSE_KEY, _
aKeyEntryNames(ii), sLevelERsEncoded )
else
call oReg.GetStringValue( HKEY_LOCAL_MACHINE, IBMHWMP_LICENSE_KEY, _
aKeyEntryNames(ii), sLevelERsEncoded )
end if

if IsNull(sLevelERsEncoded) Or IsEmpty(sLevelERsEncoded) then
call LogDebugString("!! LicManager: Registry value " + _
aKeyEntryNames(ii) + " null or empty", ERROR_LEVEL)
else
call LogDebugString(".. LicManager: " + aKeyEntryNames(ii) + _
"='" + sLevelERsEncoded + "'", INFO_LEVEL_DETAIL)
m_sLicToken = sLevelERsEncoded
sLevelERsDecoded = fDecode(sLevelERsEncoded)
call LogDebugString(".. LicManager: " + aKeyEntryNames(ii) + _
"='" + sLevelERsDecoded + "' [Decoded]", INFO_LEVEL_DETAIL)
asSplitERs = split(sLevelERsDecoded, vbTab)
if UBound(asSplitERs) &gt;= 0 then
dim jj
for jj=0 to UBound(asSplitERs)
call LogDebugString(".. LicManager: Retrieved '" + _
asSplitERs(jj) + "'", INFO_LEVEL_DETAIL)
dim oLevelER
set oLevelER = new FeatLevelER
if 0 &lt;= oLevelER.ParseLevelER( asSplitERs(jj) ) then
if 0 = nLevelsLoaded then
m_aLevelERs = array( 0 ) ' create a 1-element array of '0'
else
redim preserve m_aLevelERs( nLevelsLoaded )
end if
set m_aLevelERs( nLevelsLoaded ) = oLevelER
nLevelsLoaded = nLevelsLoaded + 1
call LogDebugString("&gt;&gt; LicManager: Parsed " + _
oLevelER.ToString(), INFO_LEVEL)
end if
next
end if
end if
end if
end if
next

end sub ' LoadFromRegistry

public sub FindBestFeatLevel( byRef oBestLevelER )
oBestLevelER = null
if not( isArray( m_aLevelERs ) ) then
exit sub
end if
if UBound(m_aLevelERs) &gt;= 0 then
dim ii, oLevelER
set oBestLevelER = m_aLevelERs(0)
for ii=1 to UBound(m_aLevelERs)
set oLevelER = m_aLevelERs(ii)
if (oLevelER.LevelMajor &gt; oBestLevelER.LevelMajor) Or _
(oLevelER.LevelMajor = oBestLevelER.LevelMajor And _
oLevelER.LevelMinor &gt; oBestLevelER.LevelMinor) then
set oBestLevelER = oLevelER
end if
next
end if
end sub

end class

class FeatLevelER

private m_levelMajor
private m_levelMinor

public property get LevelMajor
LevelMajor = m_levelMajor
end property
public property get LevelMinor
LevelMinor = m_levelMinor
end property

private sub Class_Initialize()
end sub

public function ParseLevelER( byVal sEntryValue )
dim retCode
retCode = 0
on error resume next
dim asSplit
asSplit = split( sEntryValue, "." )
if UBound(asSplit) &lt;&gt; 1 then
call LogDebugString("!! FeatLevelER.ParseLevelER: unexpected number of items in " + _
"feature level record (" + UBound(asSplit) + ")", ERROR_LEVEL)
retCode = -1
else
m_levelMajor = CInt(asSplit(0))
m_levelMinor = CInt(asSplit(1))
call LogDebugString(".. FeatLevelER.ParseLevelER: MajorVersion = " + _
CStr(m_levelMajor) + ", MinorVersion = " + CStr(m_levelMinor), INFO_LEVEL_DETAIL)
end if
on error goto 0
ParseLevelER = retCode
end function

public function ToString()
ToString = CStr(m_levelMajor) + "." + CStr(m_levelMinor)
end function

end class


' N.B. fDecode() is a verbatim copy of the one in HW MP.
' &lt;twoffer&gt; Can this be referenced instead of copied? &lt;/twoffer&gt;
Function fDecode(sStringToDecode)
'This function will decode a Base64 encoded string and returns the decoded string.
Const CharList = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
Dim iDataLength, sOutputString, iGroupInitialCharacter
sStringToDecode = Replace(Replace(Replace(sStringToDecode, vbCrLf, ""), vbTab, ""), " ", "")
iDataLength = Len(sStringToDecode)
If iDataLength Mod 4 &lt;&gt; 0 Then
fDecode = "Bad string passed to fDecode() function."
Exit Function
End If
For iGroupInitialCharacter = 1 To iDataLength Step 4
Dim iDataByteCount, iCharacterCounter, sCharacter, iData, iGroup, sPreliminaryOutString
iDataByteCount = 3
iGroup = 0
For iCharacterCounter = 0 To 3
sCharacter = Mid(sStringToDecode, iGroupInitialCharacter + iCharacterCounter, 1)
If sCharacter = "=" Then
iDataByteCount = iDataByteCount - 1
iData = 0
Else
iData = InStr(1, CharList, sCharacter, 0) - 1
If iData = -1 Then
fDecode = "Bad string passed to fDecode() function."
Exit Function
End If
End If
iGroup = 64 * iGroup + iData
Next
iGroup = Hex(iGroup)
iGroup = String(6 - Len(iGroup), "0") &amp; iGroup
sPreliminaryOutString = Chr(CByte("&amp;H" &amp; Mid(iGroup, 1, 2))) &amp; Chr(CByte("&amp;H" &amp; Mid(iGroup, 3, 2))) &amp; Chr(CByte("&amp;H" &amp; Mid(iGroup, 5, 2)))
sOutputString = sOutputString &amp; Left(sPreliminaryOutString, iDataByteCount)
Next
fDecode = sOutputString
End Function

</Script></ScriptBody>
<TimeoutSeconds>$Config/TimeoutSeconds$</TimeoutSeconds>
</DataSource>
<!--<ConditionDetection ID="CD" TypeID="System!System.ExpressionFilter">
<Expression>
<SimpleExpression>
<ValueExpression>
<XPathQuery>Property[@Name='$Config/IsDetected$']</XPathQuery>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value Type="String">true</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
</ConditionDetection>-->
</MemberModules>
<Composition>
<!--<Node ID ="CD">-->
<Node ID="DS"/>
<!--</Node>-->
</Composition>
</Composite>
</ModuleImplementation>
<OutputType>System!System.Discovery.Data</OutputType>
</DataSourceModuleType>