Discover Pools Data source module.

Microsoft.LS.2015.Discovery.PoolWatcher.DS (DataSourceModuleType)

Element properties:

TypeDataSourceModuleType
IsolationAny
AccessibilityInternal
RunAsDefault
OutputTypeSystem.Discovery.Data

Member Modules:

ID Module Type TypeId RunAs 
DS DataSource Microsoft.LS.2015.Discovery.Common.DS.ShellOut Default

Overrideable Parameters:

IDParameterTypeSelectorDisplay NameDescription
AuthTypestring$Config/AuthType$Authentication TypeAuthentication Type
TimeoutSecondsint$Config/TimeoutSeconds$Timeout in SecondsTimeout in Seconds
IntervalSecondsint$Config/IntervalSeconds$Interval SecondsInterval Seconds

Source Code:

<DataSourceModuleType ID="Microsoft.LS.2015.Discovery.PoolWatcher.DS" Accessibility="Internal" 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="TimeoutSeconds" type="xsd:integer"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="AuthType" type="xsd:string"/>
</Configuration>
<OverrideableParameters>
<OverrideableParameter ID="IntervalSeconds" Selector="$Config/IntervalSeconds$" ParameterType="int"/>
<OverrideableParameter ID="TimeoutSeconds" Selector="$Config/TimeoutSeconds$" ParameterType="int"/>
<OverrideableParameter ID="AuthType" Selector="$Config/AuthType$" ParameterType="string"/>
</OverrideableParameters>
<ModuleImplementation Isolation="Any">
<Composite>
<MemberModules>
<DataSource ID="DS" TypeID="Microsoft.LS.2015.Discovery.Common.DS.ShellOut">
<IntervalSeconds>$Config/IntervalSeconds$</IntervalSeconds>
<SyncTime/>
<ScriptName>Skype for Business Server 2015 MP Remote Watcher Discovery</ScriptName>
<ScriptFileName>RemotePoolWatcherDiscovery.ps1</ScriptFileName>
<ScriptBody><Script>
#SUMMARY####################################################################
# 1. Validate Health Monitoring XML file.
# 2. Deserialize Health Monitoring Data into Hashtable.
# 3. Iterate over Hastable and Submit Discovery Data.
#############################################################################

#LOGS &amp; EXCEPTIONS###########################################################
$CS_MODULE_NAME = "SkypeForBusiness"
$CS_MODULE_ADDED = "SkypeForBusiness Module is added";
$CS_MODULE_ALREADY_LOADED = "SkypeForBusiness Module is already loaded. No need to reload."
$CS_MODULE_FAILED_LOAD = "Failed to load SkypeForBusiness Module. Error: {0}."
#############################################################################

#Helper Functions [GENERAL]##################################################
function IsCSModuleLoaded()
{
(get-module $CS_MODULE_NAME ) -ne $null
}

function LoadCSModule()
{
# Script execution are managed by SCOM powershell module.
# MonitoringHost.exe is hosting powershell runspaces.
# SCOM might run the scripts on the same process and reuse the app domain if neccesary.
# Double check on wheter module is loaded or not.
if (IsCSModuleLoaded)
{
TRACE ($CS_MODULE_ALREADY_LOADED)
}
else
{
# Refresh PSModulePath in case new build is deployed into different folder but SCOM Agent is not restarted
$psPaths = $env:PSModulePath -split ";"
$env:PSModulePath = ($psPaths + ([Environment]::GetEnvironmentVariable("PSModulePath", "Machine") -split ";" | ?{$psPaths -notcontains $_})) -join ";"

# Due to possible race condition between steps of checking module is loaded and loading module steps,
# we need to double check after module loading attempt.
$moduleImported = $false
$retryCount = 0

while (!$moduleImported -and $retryCount -lt 10)
{
try
{
Import-module $CS_MODULE_NAME -ErrorAction SilentlyContinue
$moduleImported = $true
}
catch
{
$retryCount= $retryCount + 1
TRACE ("Retrying Import Module" + $retryCount)
}
}
if (IsCSModuleLoaded)
{
TRACE ($CS_MODULE_ADDED)
}
else
{
$lastError = $error[0]
TRACE ($CS_MODULE_FAILED_LOAD -f $lastError)
}
}
}
#############################################################################

# ST Mapping for Class and Relationships ####################################
$stWatchers =
@{
"Registration"= "$MPElement[Name='Microsoft.LS.2015.PoolWatcher.Registration']$";
"IM"= "$MPElement[Name='Microsoft.LS.2015.PoolWatcher.IM']$";
"GroupIM"= "$MPElement[Name='Microsoft.LS.2015.PoolWatcher.GroupIM']$";
"P2PAV"= "$MPElement[Name='Microsoft.LS.2015.PoolWatcher.P2PAV']$";
"AVConference"= "$MPElement[Name='Microsoft.LS.2015.PoolWatcher.AVConference']$";
"ASConference"= "$MPElement[Name='Microsoft.LS.2015.PoolWatcher.ASConference']$";
"Presence"= "$MPElement[Name='Microsoft.LS.2015.PoolWatcher.Presence']$";
"ABS"= "$MPElement[Name='Microsoft.LS.2015.PoolWatcher.ABS']$";
"ABWQ"= "$MPElement[Name='Microsoft.LS.2015.PoolWatcher.ABWQ']$";
"MCXP2PIM"= "$MPElement[Name='Microsoft.LS.2015.PoolWatcher.MCXP2PIM']$";
"ExUMConnectivity"= "$MPElement[Name='Microsoft.LS.2015.PoolWatcher.ExUMConnectivity']$";
"JoinLauncher"= "$MPElement[Name='Microsoft.LS.2015.PoolWatcher.JoinLauncher']$";
"PersistentChatMessage"= "$MPElement[Name='Microsoft.LS.2015.PoolWatcher.PersistentChatMessage']$";
"DataConference"= "$MPElement[Name='Microsoft.LS.2015.PoolWatcher.DataConference']$";
"XmppIM"= "$MPElement[Name='Microsoft.LS.2015.PoolWatcher.XmppIM']$";
"UnifiedContactStore"= "$MPElement[Name='Microsoft.LS.2015.PoolWatcher.UnifiedContactStore']$";
"AVEdgeConnectivity"= "$MPElement[Name='Microsoft.LS.2015.PoolWatcher.AVEdgeConnectivity']$";
"DialinConferencing"= "$MPElement[Name='Microsoft.LS.2015.PoolWatcher.DialinConferencing']$";
"UcwaConference"= "$MPElement[Name='Microsoft.LS.2015.PoolWatcher.UcwaConference']$";
"LyncSkypeIM"= "$MPElement[Name='Microsoft.LS.2015.PoolWatcher.LyncSkypeIM']$";
"LyncSkypeMedia"= "$MPElement[Name='Microsoft.LS.2015.PoolWatcher.LyncSkypeMedia']$";
"TenantPowershell"= "$MPElement[Name='Microsoft.LS.2015.PoolWatcher.TenantPowershell']$";
"P2PVideoInteropServerSipTrunkAV"= "$MPElement[Name='Microsoft.LS.2015.PoolWatcher.P2PVideoInteropServerSipTrunkAV']$";
}

$poolWatcherHostsStWatcherRelationship =
@{
"Registration"= "$MPElement[Name='Microsoft.LS.2015.Relationship.PoolWatcherHostsRegistration']$";
"IM"= "$MPElement[Name='Microsoft.LS.2015.Relationship.PoolWatcherHostsIM']$";
"GroupIM"= "$MPElement[Name='Microsoft.LS.2015.Relationship.PoolWatcherHostsGroupIM']$";
"P2PAV"= "$MPElement[Name='Microsoft.LS.2015.Relationship.PoolWatcherHostsP2PAV']$";
"AVConference"= "$MPElement[Name='Microsoft.LS.2015.Relationship.PoolWatcherHostsAVConference']$";
"ASConference"= "$MPElement[Name='Microsoft.LS.2015.Relationship.PoolWatcherHostsASConference']$";
"Presence"= "$MPElement[Name='Microsoft.LS.2015.Relationship.PoolWatcherHostsPresence']$";
"ABS"= "$MPElement[Name='Microsoft.LS.2015.Relationship.PoolWatcherHostsABS']$";
"ABWQ"= "$MPElement[Name='Microsoft.LS.2015.Relationship.PoolWatcherHostsABWQ']$";
"MCXP2PIM"= "$MPElement[Name='Microsoft.LS.2015.Relationship.PoolWatcherHostsMCXP2PIM']$";
"ExUMConnectivity"= "$MPElement[Name='Microsoft.LS.2015.Relationship.PoolWatcherHostsExUMConnectivity']$";
"JoinLauncher"= "$MPElement[Name='Microsoft.LS.2015.Relationship.PoolWatcherHostsJoinLauncher']$";
"PersistentChatMessage"= "$MPElement[Name='Microsoft.LS.2015.Relationship.PoolWatcherHostsPersistentChatMessage']$";
"DataConference"= "$MPElement[Name='Microsoft.LS.2015.Relationship.PoolWatcherHostsDataConference']$";
"XmppIM"= "$MPElement[Name='Microsoft.LS.2015.Relationship.PoolWatcherHostsXmppIM']$";
"UnifiedContactStore"= "$MPElement[Name='Microsoft.LS.2015.Relationship.PoolWatcherHostsUnifiedContactStore']$";
"AVEdgeConnectivity"= "$MPElement[Name='Microsoft.LS.2015.Relationship.PoolWatcherHostsAVEdgeConnectivity']$";
"DialinConferencing"= "$MPElement[Name='Microsoft.LS.2015.Relationship.PoolWatcherHostsDialinConferencing']$";
"UcwaConference"= "$MPElement[Name='Microsoft.LS.2015.Relationship.PoolWatcherHostsUcwaConference']$";
"LyncSkypeIM"= "$MPElement[Name='Microsoft.LS.2015.Relationship.PoolWatcherHostsLyncSkypeIM']$";
"LyncSkypeMedia"= "$MPElement[Name='Microsoft.LS.2015.Relationship.PoolWatcherHostsLyncSkypeMedia']$";
"TenantPowershell"= "$MPElement[Name='Microsoft.LS.2015.Relationship.PoolWatcherHostsTenantPowershell']$";
"P2PVideoInteropServerSipTrunkAV"= "$MPElement[Name='Microsoft.LS.2015.Relationship.PoolWatcherHostsP2PVideoInteropServerSipTrunkAV']$";
}

#############################################################################

#CONSTANTS###################################################################
$TARGET_FQDN_PROPERTY_NAME = "TargetFqdn"
$AUTHENTICATION_NAME = "Authentication"

$TESTS = "Tests"
$EXTENDED_TESTS = "ExtendedTests"
$EXTENDED_TEST_NAME = "ExtendedTestName"
$EXTENDED_TEST_TYPE = "ExtendedTestType"

$ACP_TEST_TYPE = "AudioConferencingProvider"
$PSTN_TEST_TYPE = "PSTN"

$READ_WNC_PROCESS_STARTED = "Reading watcher node configuration process is started.`n"
$READ_WNC_FOR_POOL_WATCHER = "Reading watcher node configuration for the pool completed:`n[{0}]`n"
$READ_WNC_FOR_POOL_WATCHER_SKIPPED = "Reading watcher node configuration for the disabled pool [{0}] is skipped.`n"
$READ_WNC_PROCESS_ENDED = "Reading watcher node configuration process is ended.`n"
$READ_WNC_UNSUPPORTED_EXTENDED_TEST_TYPE = "Skipping discovery for extended test {0} due to unsupported extended test type {1}.`n"
$READ_WNC_UNSUPPORTED_TEST_TYPE = "Unsupported test type {0}. Skipping discovery.`n"
$SUBMITTING_DISCOVERY_DATA_STARTED = "Submitting discovery data started.`n"
$SUBMITTING_DISCOVERY_DATA_ENDED = "Submitting discovery data successfully ended.`n"

$POOL_DISPLAY_NAME_FORMAT = "Pool [{0}]"
$POOL_WATCHER_DISPLAY_NAME_FORMAT = "Pool [{0}] watched by [{1}]"
$ACP_WATCHER_DISPLAY_NAME_FORMAT = "Audio Conferencing Provider Test for pool [{0}] test name [{1}] watched by [{2}]"
$PSTN_WATCHER_DISPLAY_NAME_FORMAT = "PSTN Test for pool [{0}] test name [{1}] watched by [{2}]"
$TEST_WATCHER_DISPLAY_NAME_FORMAT = "{0} Test for pool [{1}] watched by [{2}]"
#############################################################################

function ReadWatcherNodeConfiguration
{
TRACE($READ_WNC_PROCESS_STARTED)
$watchernodeconfiguration = @(get-cswatchernodeconfiguration)

$deserializedPoolWatchers= @()
foreach ($targetPool in strip-null($watchernodeconfiguration))
{
# If targetPool is disabled, skip discovery.
if ($targetPool.Enabled -eq $false)
{
TRACE($READ_WNC_FOR_POOL_WATCHER_SKIPPED -f $targetPool.TargetFqdn)
continue
}

$poolWatcherSettings = @{} #A Hash
$targetFqdn = $targetPool.TargetFqdn
$authentication = "$Config/AuthType$"

$poolWatcherSettings.Add($TARGET_FQDN_PROPERTY_NAME ,$targetFqdn)
$poolWatcherSettings.Add($AUTHENTICATION_NAME ,$authentication)

$deserializedTests = @()
foreach ($test in strip-null($targetPool.Tests))
{
$deserializedTests += $test
}

$poolWatcherSettings.Add($TESTS,$deserializedTests)

$deserializedExtendedTests = @()
foreach ($extendedTest in strip-null($targetPool.ExtendedTests))
{
$extendedTestSettings = @{} #A Hash
$extendedTestSettings.Add($EXTENDED_TEST_NAME ,$extendedTest.Name)
$extendedTestSettings.Add($EXTENDED_TEST_TYPE ,$extendedTest.TestType)
$deserializedExtendedTests += $extendedTestSettings
}
$poolWatcherSettings.Add($EXTENDED_TESTS ,$deserializedExtendedTests)

$deserializedPoolWatchers += $poolWatcherSettings
TRACE($READ_WNC_FOR_POOL_WATCHER -f ($poolWatcherSettings | out-string))
}
$deserializedPoolWatchers
TRACE($READ_WNC_PROCESS_ENDED)
}

function SumbitDiscoveryData {
param($deserializedPoolWatchers)
TRACE($SUBMITTING_DISCOVERY_DATA_STARTED)

$DiscoveryData = GetDiscoveryData
$watcherNode = $DiscoveryData.CreateClassInstance("$MPElement[Name='Microsoft.LS.2015.WatcherNode.RemoteWatcher.SyntheticTransaction']$");
$watcherNode.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", $TargetComputer);

foreach ($deserializedPoolWatcher in strip-null($deserializedPoolWatchers))
{
$pool = $DiscoveryData.CreateClassInstance("$MPElement[Name='Microsoft.LS.2015.Pool']$");
$pool.AddProperty("$MPElement[Name='Microsoft.LS.2015.Pool']/PoolFqdn$", $deserializedPoolWatcher[$TARGET_FQDN_PROPERTY_NAME]);
$pool.AddProperty("$MPElement[Name="System!System.Entity"]/DisplayName$", ($POOL_DISPLAY_NAME_FORMAT -f $deserializedPoolWatcher[$TARGET_FQDN_PROPERTY_NAME]));
$DiscoveryData.AddInstance($pool);

$poolWatcher = $DiscoveryData.CreateClassInstance("$MPElement[Name='Microsoft.LS.2015.PoolWatcher']$");
$poolWatcher.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", $TargetComputer);
$poolWatcher.AddProperty("$MPElement[Name='Microsoft.LS.2015.PoolWatcher']/WatcherNodeFqdn$", $TargetComputer);
$poolWatcher.AddProperty("$MPElement[Name='Microsoft.LS.2015.PoolWatcher']/TargetFqdn$", $deserializedPoolWatcher[$TARGET_FQDN_PROPERTY_NAME]);
$poolWatcher.AddProperty("$MPElement[Name='Microsoft.LS.2015.PoolWatcher']/Authentication$", $deserializedPoolWatcher[$AUTHENTICATION_NAME]);
$poolWatcher.AddProperty("$MPElement[Name="System!System.Entity"]/DisplayName$", ($POOL_WATCHER_DISPLAY_NAME_FORMAT -f $deserializedPoolWatcher[$TARGET_FQDN_PROPERTY_NAME], $TargetComputer));
$DiscoveryData.AddInstance($poolWatcher)

$PoolContainsPoolWatcher =
$DiscoveryData.CreateRelationshipInstance("$MPElement[Name='Microsoft.LS.2015.Relationship.PoolContainsPoolWatcher']$");
$PoolContainsPoolWatcher.Source = $pool;
$PoolContainsPoolWatcher.Target = $poolWatcher;
$DiscoveryData.AddInstance($PoolContainsPoolWatcher);

$WatcherNodeHostsPoolWatcher =
$DiscoveryData.CreateRelationshipInstance("$MPElement[Name='Microsoft.LS.2015.Relationship.SyntheticTransactionWatcherNodeHostsPoolWatcher']$");
$WatcherNodeHostsPoolWatcher.Source = $watcherNode;
$WatcherNodeHostsPoolWatcher.Target = $poolWatcher;
$DiscoveryData.AddInstance($WatcherNodeHostsPoolWatcher);

foreach ($test in strip-null($deserializedPoolWatcher[$TESTS]))
{
$testWatcerClassId = $stWatchers[$test]
$poolWatcherHostsTestWatcherRelationshipId = $poolWatcherHostsStWatcherRelationship[$test]
if (($testWatcerClassId -eq $null) -or ($poolWatcherHostsTestWatcherRelationshipId -eq $null))
{
TRACE ($READ_WNC_UNSUPPORTED_TEST_TYPE -f $test)
}
else
{
$testWatcher = $DiscoveryData.CreateClassInstance($testWatcerClassId);
$testWatcher.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", $TargetComputer);
$testWatcher.AddProperty("$MPElement[Name='Microsoft.LS.2015.PoolWatcher']/TargetFqdn$", $deserializedPoolWatcher[$TARGET_FQDN_PROPERTY_NAME]);
$testWatcher.AddProperty("$MPElement[Name="System!System.Entity"]/DisplayName$", ($TEST_WATCHER_DISPLAY_NAME_FORMAT -f $test, $deserializedPoolWatcher[$TARGET_FQDN_PROPERTY_NAME], $TargetComputer));
$DiscoveryData.AddInstance($testWatcher)

$PoolWatcherHostsTestWatcher =
$DiscoveryData.CreateRelationshipInstance($poolWatcherHostsTestWatcherRelationshipId);
$PoolWatcherHostsTestWatcher.Source = $poolWatcher;
$PoolWatcherHostsTestWatcher.Target = $testWatcher;
$DiscoveryData.AddInstance($PoolWatcherHostsTestWatcher);
TRACE ($DISCOVERY_SUCCESS -f "Test Watcher", $test)
}
}

foreach ($extendedTest in strip-null($deserializedPoolWatcher[$EXTENDED_TESTS]))
{
if($extendedTest[$EXTENDED_TEST_TYPE] -eq $PSTN_TEST_TYPE)
{
$pstnWatcher = $DiscoveryData.CreateClassInstance("$MPElement[Name='Microsoft.LS.2015.PoolWatcher.PSTN']$");
$pstnWatcher.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", $TargetComputer);
$pstnWatcher.AddProperty("$MPElement[Name='Microsoft.LS.2015.PoolWatcher']/TargetFqdn$", $deserializedPoolWatcher[$TARGET_FQDN_PROPERTY_NAME]);
$pstnWatcher.AddProperty("$MPElement[Name='Microsoft.LS.2015.PoolWatcher.PSTN']/Name$", $extendedTest[$EXTENDED_TEST_NAME]);
$pstnWatcherDisplayName = $PSTN_WATCHER_DISPLAY_NAME_FORMAT -f $deserializedPoolWatcher[$TARGET_FQDN_PROPERTY_NAME], $extendedTest[$EXTENDED_TEST_NAME], $TargetComputer
$pstnWatcher.AddProperty("$MPElement[Name="System!System.Entity"]/DisplayName$", $pstnWatcherDisplayName);
$DiscoveryData.AddInstance($pstnWatcher)

$PoolWatcherHostsPSTNWatcher =
$DiscoveryData.CreateRelationshipInstance("$MPElement[Name='Microsoft.LS.2015.Relationship.PoolWatcherHostsPSTN']$");
$PoolWatcherHostsPSTNWatcher.Source = $poolWatcher;
$PoolWatcherHostsPSTNWatcher.Target = $pstnWatcher;
$DiscoveryData.AddInstance($PoolWatcherHostsPSTNWatcher);
TRACE ($DISCOVERY_SUCCESS -f "PSTN Test Watcher", $extendedTest[$EXTENDED_TEST_NAME])
}
elseif ($extendedTest[$EXTENDED_TEST_TYPE] -eq $ACP_TEST_TYPE)
{
$acpWatcher = $DiscoveryData.CreateClassInstance("$MPElement[Name='Microsoft.LS.2015.PoolWatcher.AudioConferencingProvider']$");
$acpWatcher.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", $TargetComputer);
$acpWatcher.AddProperty("$MPElement[Name='Microsoft.LS.2015.PoolWatcher']/TargetFqdn$", $deserializedPoolWatcher[$TARGET_FQDN_PROPERTY_NAME]);
$acpWatcher.AddProperty("$MPElement[Name='Microsoft.LS.2015.PoolWatcher.AudioConferencingProvider']/Name$", $extendedTest[$EXTENDED_TEST_NAME]);
$acpWatcherDisplayName = $ACP_WATCHER_DISPLAY_NAME_FORMAT -f $deserializedPoolWatcher[$TARGET_FQDN_PROPERTY_NAME], $extendedTest[$EXTENDED_TEST_NAME], $TargetComputer
$acpWatcher.AddProperty("$MPElement[Name="System!System.Entity"]/DisplayName$", $acpWatcherDisplayName);
$DiscoveryData.AddInstance($acpWatcher)

$PoolWatcherHostsACPWatcher =
$DiscoveryData.CreateRelationshipInstance("$MPElement[Name='Microsoft.LS.2015.Relationship.PoolWatcherHostsAudioConferencingProvider']$");
$PoolWatcherHostsACPWatcher.Source = $poolWatcher;
$PoolWatcherHostsACPWatcher.Target = $acpWatcher;
$DiscoveryData.AddInstance($PoolWatcherHostsACPWatcher);
TRACE ($DISCOVERY_SUCCESS -f "Audio Conferencing Provider Test Watcher", $extendedTest[$EXTENDED_TEST_NAME])
}
else
{
TRACE ($READ_WNC_UNSUPPORTED_EXTENDED_TEST_TYPE -f $extendedTest[$EXTENDED_TEST_NAME], $extendedTest[$EXTENDED_TEST_TYPE])
}
}
TRACE ($DISCOVERY_SUCCESS -f "Pool Watcher", $deserializedPoolWatcher[$TARGET_FQDN_PROPERTY_NAME])
}
TRACE ($DISCOVERY_SUCCESS -f "Synthetic Transactions Watcher Node", $TargetComputer)
TRACE($SUBMITTING_DISCOVERY_DATA_ENDED)
}

LoadCSModule

$wnConfig = ReadWatcherNodeConfiguration

SumbitDiscoveryData $wnConfig
</Script></ScriptBody>
<TimeoutSeconds>$Config/TimeoutSeconds$</TimeoutSeconds>
<EventId>331</EventId>
<TargetComputer>$Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/PrincipalName$</TargetComputer>
</DataSource>
</MemberModules>
<Composition>
<Node ID="DS"/>
</Composition>
</Composite>
</ModuleImplementation>
<OutputType>System!System.Discovery.Data</OutputType>
</DataSourceModuleType>