Hosted Cache Client Node Hierarchy Discovery

Microsoft.Windows.BranchCache.PowerShell.HostedCacheClientNodeHierarchy.Discovery (Discovery)

Discovers the Hosted Cache Branch to which this computer belongs based on the hosted cache server that is specified by Group Policy.

Knowledge Base article:

Summary

Discovers which hosted cache clients are connecting to hosted cache servers, and identifies the hosted cache servers.

Element properties:

TargetMicrosoft.Windows.BranchCache.PowerShell.HostedCacheClientNode
EnabledTrue
Frequency14400
RemotableFalse

Object Discovery Details:

Discovered Classes and their attribuets:
Discovered relationships and their attribuets:

Member Modules:

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

Source Code:

<Discovery ID="Microsoft.Windows.BranchCache.PowerShell.HostedCacheClientNodeHierarchy.Discovery" Enabled="true" Target="Microsoft.Windows.BranchCache.PowerShell.HostedCacheClientNode" ConfirmDelivery="false" Remotable="true" Priority="Normal">
<Category>Discovery</Category>
<DiscoveryTypes>
<DiscoveryClass TypeID="Microsoft.Windows.BranchCache.HostedCacheClientNode">
<Property TypeID="Microsoft.Windows.BranchCache.ClientSideServiceBase" PropertyID="NodeName"/>
<Property PropertyID="HostedCacheName"/>
<Property PropertyID="GPHostedCacheName"/>
<Property PropertyID="GPHostedCacheNameExists"/>
</DiscoveryClass>
<DiscoveryClass TypeID="Microsoft.Windows.BranchCache.HostedCacheClientGroup">
<Property PropertyID="HostedCacheServerGroupName"/>
</DiscoveryClass>
<DiscoveryClass TypeID="Microsoft.Windows.BranchCache.HostedCacheGroup">
<Property PropertyID="HostedCacheName"/>
</DiscoveryClass>
<DiscoveryClass TypeID="Microsoft.Windows.BranchCache.BranchCacheApp"/>
<DiscoveryRelationship TypeID="Microsoft.Windows.BranchCache.HostedCacheClientGroupContainsHostedCacheClientNode"/>
<DiscoveryRelationship TypeID="Microsoft.Windows.BranchCache.HostedCacheGroupContainsHostedCacheClientGroup"/>
<DiscoveryRelationship TypeID="Microsoft.Windows.BranchCache.BranchCacheAppHostsHostedCacheGroup"/>
</DiscoveryTypes>
<DataSource ID="DS" TypeID="Windows!Microsoft.Windows.TimedScript.DiscoveryProvider">
<IntervalSeconds>14400</IntervalSeconds>
<SyncTime/>
<ScriptName>BranchCache.PowerShell.HostedCacheClientNodeHierarchy.Discovery.vbs</ScriptName>
<Arguments>$MPElement$ $Target/Id$ $Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/PrincipalName$ $Target/Property[Type="Microsoft.Windows.BranchCache.HostedCacheClientNode"]/GPHostedCacheNameExists$ $Target/Property[Type="Microsoft.Windows.BranchCache.HostedCacheClientNode"]/GPHostedCacheName$</Arguments>
<ScriptBody><Script>Option Explicit
SetLocale("en-us")

Function GetStdRegProvObject
Dim strComputer
strComputer = "."
Set GetStdRegProvObject = GetObject("winmgmts:\\" &amp; strComputer &amp; "\root\default:StdRegProv")
End Function

Function GetStringValue(strKeyPath, strValueName)
Const HKEY_LOCAL_MACHINE = &amp;H80000002
Dim objRegistry
Set objRegistry = GetStdRegProvObject
objRegistry.GetStringValue HKEY_LOCAL_MACHINE, strKeyPath, strValueName, GetStringValue
Set objRegistry = Nothing
End Function

Function GetDWORDValue(strKeyPath, strValueName)
Const HKEY_LOCAL_MACHINE = &amp;H80000002
Dim objRegistry
Set objRegistry = GetStdRegProvObject
objRegistry.GetDWORDValue HKEY_LOCAL_MACHINE, strKeyPath, strValueName, GetDWORDValue
Set objRegistry = Nothing
End Function

Function GetValues(strKeyPath)
Const HKEY_LOCAL_MACHINE = &amp;H80000002
Dim objRegistry
Set objRegistry = GetStdRegProvObject
objRegistry.EnumValues HKEY_LOCAL_MACHINE, strKeyPath, GetValues, Nothing
Set objRegistry = Nothing
End Function

Function StringValueExists(strKeyPath, strValueName)
StringValueExists = Not IsNull(GetStringValue(strKeyPath, strValueName))
End Function

Function ValuesExist(strKeyPath)
ValuesExist = Not IsNull(GetValues(strKeyPath))
End Function

Function GetMultipleServerGroup(strKeyPath)
Dim strValueNames, strValueName, strValue, strServerGroup
strValueNames = GetValues(strKeyPath)
For Each strValueName in strValueNames
If IsNumeric(strValueName) Then
strValue = GetStringValue(strKeyPath, strValueName)
If strValueName = strValueNames(0) Then
strServerGroup = strValue
Else
strServerGroup = strServerGroup &amp; ", " &amp; strValue
End If
End If
Next
GetMultipleServerGroup = strServerGroup
End Function

Dim oArgs
Set oArgs = WScript.Arguments
If oArgs.Count &lt; 4 Then
Wscript.Quit -1
End If

Dim SourceID, ManagedEntityId, TargetComputer, HostedCache, SingleHostedCache, GPHostedCache, GPHostedCacheExists

SourceId = oArgs(0)
ManagedEntityId = oArgs(1)
TargetComputer = oArgs(2)
GPHostedCacheExists = oArgs(3)

SingleHostedCache = ""
GPHostedCache = ""
HostedCache = ""

If GPHostedCacheExists = "True" Then
If oArgs.Count &lt; 5 Then
Wscript.Quit -1
End If
GPHostedCache = oArgs(4)
End If

'Legacy Hosted Cache Key
Const strConnectionKey = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\PeerDist\HostedCache\Connection"
'Auto-Discovery (SCP) Hosted Cache Keys
Const strMultipleServersKey = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\PeerDist\HostedCache\MultipleServers"
Const strGPMultipleServersKey = "SOFTWARE\Policies\Microsoft\PeerDist\HostedCache\MultipleServers"
'Windows 8 Hosted Cache Keys
Const strDiscoveryKey = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\PeerDist\HostedCache\Discovery"
Const strGPDiscoveryKey = "SOFTWARE\Policies\Microsoft\PeerDist\HostedCache\Discovery"
Const strDiscoveredServersKey = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\PeerDist\HostedCache\Discovery\DiscoveredServers"

If GPHostedCacheExists = "False" Then
'Windows 8 Hosted Cache (Group Policy)
If ValuesExist(strGPMultipleServersKey) Then
HostedCache = GetMultipleServerGroup(strGPMultipleServersKey)
GPHostedCacheExists = "True"
GPHostedCache = HostedCache
'Windows 8 Hosted Cache (Local)
ElseIf ValuesExist(strMultipleServersKey) Then
HostedCache = GetMultipleServerGroup(strMultipleServersKey)
'Auto-Discovery (SCP) Hosted Cache (Group Policy)
ElseIf GetDWORDValue(strGPDiscoveryKey, "SCPDiscoveryEnabled") &gt;= 1 And ValuesExist(strDiscoveredServersKey) Then
HostedCache = GetMultipleServerGroup(strDiscoveredServersKey)
GPHostedCacheExists = "True"
GPHostedCache = HostedCache
'Auto-Discovery (SCP) Hosted Cache (Local)
ElseIf GetDWORDValue(strDiscoveryKey, "SCPDiscoveryEnabled") &gt;= 1 And ValuesExist(strDiscoveredServersKey) Then
HostedCache = GetMultipleServerGroup(strDiscoveredServersKey)
'Legacy Hosted Cache
ElseIf StringValueExists(strConnectionKey, "Location") Then
HostedCache = GetStringValue(strConnectionKey, "Location")
SingleHostedCache = HostedCache
Else
WScript.Quit -1
End If
End If

''
'' Declare some working variables and then create an empty discovery payload.
''
Dim oAPI, oDiscoveryData, cInst, mInst, bInst, appInst, relInst, relInst2, relInst3

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

''
'' Now, let's discover the consensus node and set its properties. When done we add it to the discovery packet
''
set cInst = oDiscoveryData.CreateClassInstance("$MPElement[Name='Microsoft.Windows.BranchCache.PowerShell.HostedCacheClientNode']$")

call cInst.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", TargetComputer)
call cInst.AddProperty("$MPElement[Name='Microsoft.Windows.BranchCache.ClientSideServiceBase']/NodeName$", TargetComputer)
call cInst.AddProperty("$MPElement[Name='Microsoft.Windows.BranchCache.HostedCacheClientNode']/HostedCacheName$", SingleHostedCache)
call cInst.AddProperty("$MPElement[Name='Microsoft.Windows.BranchCache.HostedCacheClientNode']/GPHostedCacheName$", GPHostedCache)
call cInst.AddProperty("$MPElement[Name='Microsoft.Windows.BranchCache.HostedCacheClientNode']/GPHostedCacheNameExists$", GPHostedCacheExists)

call cInst.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", TargetComputer)
call oDiscoveryData.AddInstance(cInst)

''
'' Since we are using "contains" - we have to now discover the class instance above us. If it is
'' already discovered, Ops Manager will recognize this as a reference count increase and not a
'' separate discovery because the key property is the same.
''
set mInst = oDiscoveryData.CreateClassInstance("$MPElement[Name='Microsoft.Windows.BranchCache.HostedCacheClientGroup']$")
If GPHostedCacheExists = "True" Then
call mInst.AddProperty("$MPElement[Name='Microsoft.Windows.BranchCache.HostedCacheClientGroup']/HostedCacheServerGroupName$", GPHostedCache)
call mInst.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", "HostedCache: "+ GPHostedCache)
Else
call mInst.AddProperty("$MPElement[Name='Microsoft.Windows.BranchCache.HostedCacheClientGroup']/HostedCacheServerGroupName$", HostedCache)
call mInst.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", "HostedCache: "+ HostedCache)
End If

call oDiscoveryData.AddInstance(mInst)

''
'' Now we have to also create an instance of the relationship to link this HostedCacheClientNode to its parent
''
set relInst = oDiscoveryData.CreateRelationshipInstance("$MPElement[Name='Microsoft.Windows.BranchCache.PowerShell.HostedCacheClientGroupContainsHostedCacheClientNode']$")
relInst.Source = mInst
relInst.Target = cInst
call oDiscoveryData.AddInstance(relInst)

set bInst = oDiscoveryData.CreateClassInstance("$MPElement[Name='Microsoft.Windows.BranchCache.HostedCacheGroup']$")
call bInst.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", "Hosted Caches")
call bInst.AddProperty("$MPElement[Name='Microsoft.Windows.BranchCache.HostedCacheGroup']/HostedCacheName$", "Hosted Caches")
call oDiscoveryData.AddInstance(bInst)

''
'' Now we have to also create an instance of the relationship to link this HostedCacheGroup to its parent
''
set relInst2 = oDiscoveryData.CreateRelationshipInstance("$MPElement[Name='Microsoft.Windows.BranchCache.HostedCacheGroupContainsHostedCacheClientGroup']$")

relInst2.Source = bInst
relInst2.Target = mInst
call oDiscoveryData.AddInstance(relInst2)

''
'' BranchCacheAppHostsHostedCacheGroup is using containment
'' We must also discover the BranchCacheApp and create that relationship
''

set appInst = oDiscoveryData.CreateClassInstance("$MPElement[Name='Microsoft.Windows.BranchCache.BranchCacheApp']$")
call appInst.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", "BranchCache")
call oDiscoveryData.AddInstance(appInst)

set relInst3 = oDiscoveryData.CreateRelationshipInstance("$MPElement[Name='Microsoft.Windows.BranchCache.BranchCacheAppHostsHostedCacheGroup']$")

relInst3.Source = appInst
relInst3.Target = bInst
call oDiscoveryData.AddInstance(relInst3)

''
'' To force the RMS to re-assign the local agent as the managing agent for the discovered HostedCacheClientNode (cInst)
'' we have to get a reference to the local health service class and then create a SPECIAL SECRET relationship :)

Dim oHealthServiceInstance, oHsCnRel, OHsCnRel2

Set oHealthServiceInstance = oDiscoveryData.CreateClassInstance( "$MPElement[Name='SC!Microsoft.SystemCenter.HealthService']$" )
call oHealthServiceInstance.AddProperty ("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", TargetComputer )

call oDiscoveryData.AddInstance(oHealthServiceInstance)

set oHsCnRel = oDiscoveryData.CreateRelationshipInstance("$MPElement[Name='SC!Microsoft.SystemCenter.HealthServiceShouldManageEntity']$")
oHsCnRel.Source = oHealthServiceInstance
oHsCnRel.Target = cInst

call oDiscoveryData.AddInstance(oHsCnRel)

set oHsCnRel2 = oDiscoveryData.CreateRelationshipInstance("$MPElement[Name='SC!Microsoft.SystemCenter.HealthServiceShouldManageEntity']$")
oHsCnRel2.Source = oHealthServiceInstance
oHsCnRel2.Target = mInst

call oDiscoveryData.AddInstance(oHsCnRel2)

''
'' And now we just return the discovery data
''
Call oAPI.Return(oDiscoveryData)</Script></ScriptBody>
<TimeoutSeconds>300</TimeoutSeconds>
</DataSource>
</Discovery>