LS Topology Discovery Data source module.

Microsoft.LS.2013.Discovery.Topology.DS (DataSourceModuleType)

Element properties:

TypeDataSourceModuleType
IsolationAny
AccessibilityInternal
RunAsDefault
OutputTypeSystem.Discovery.Data

Member Modules:

ID Module Type TypeId RunAs 
DS DataSource Microsoft.LS.2013.Discovery.Common.LyncModule.DS Default

Overrideable Parameters:

IDParameterTypeSelectorDisplay NameDescription
IntervalSecondsint$Config/IntervalSeconds$Interval SecondsInterval Seconds
TimeoutSecondsint$Config/TimeoutSeconds$Timeout in SecondsTimeout in Seconds

Source Code:

<DataSourceModuleType ID="Microsoft.LS.2013.Discovery.Topology.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"/>
</Configuration>
<OverrideableParameters>
<OverrideableParameter ID="IntervalSeconds" Selector="$Config/IntervalSeconds$" ParameterType="int"/>
<OverrideableParameter ID="TimeoutSeconds" Selector="$Config/TimeoutSeconds$" ParameterType="int"/>
</OverrideableParameters>
<ModuleImplementation Isolation="Any">
<Composite>
<MemberModules>
<DataSource ID="DS" TypeID="Microsoft.LS.2013.Discovery.Common.LyncModule.DS">
<IntervalSeconds>$Config/IntervalSeconds$</IntervalSeconds>
<SyncTime/>
<ScriptName>Lync Server MP Machine Topology Discovery</ScriptName>
<ScriptFileName>DiscoverMachine.ps1</ScriptFileName>
<ScriptBody><Script>
#############################################################################
# 1. Discover Deployment.
# 2. Discover Site.
# 3. Discover DeploymentContainsSite relationship.
# 4. Foreach Cluster:
# a. Discover SiteContainsCluster relationship.
# b. Get list of roles for the cluster.
# c. Foreach Role:
# d. Discover Role.
# e. Discover all belonging Component.
# f. Discover RoleHostsComponents relationship.
# NOTE
# Reason being, Microsoft.Windows.TimedPowerShell.DiscoveryProvider's
# ParameterBinding logic cannot accept a bool value and internally casts and passes
# this parameter as a string type to the script function. This results in a
# System.Management.Automation.ParameterBindingArgumentTransformationException.
# Workaround is to define the configuration parameter as bool type
# (thus only accepts two values of true or false ), but process it as a
# string type within this script.
#############################################################################


#Component Role Mapping#######################################################
$componentMap =
@{
"Common"=
@(,
("Common" ,"$MPElement[Name='Microsoft.LS.2013.Component.Common']$")
);
"CentralMgmt"=
@(
("CMSFileTransfer" ,"$MPElement[Name='Microsoft.LS.2013.Component.CMSFileTransfer']$"),
("CMSMaster" ,"$MPElement[Name='Microsoft.LS.2013.Component.CMSMaster']$")
);
"ConfServices"=
@(
("IMConf" ,"$MPElement[Name='Microsoft.LS.2013.Component.IMConf']$"),
("PhoneConf" ,"$MPElement[Name='Microsoft.LS.2013.Component.PhoneConf']$"),
("AppSharingConf" ,"$MPElement[Name='Microsoft.LS.2013.Component.AppSharingConf']$"),
("AVConf" ,"$MPElement[Name='Microsoft.LS.2013.Component.AVConf']$"),
("DataConf" ,"$MPElement[Name='Microsoft.LS.2013.Component.DataConf']$")
);
"EdgeServer"=
@(
("AccessEdge" ,"$MPElement[Name='Microsoft.LS.2013.Component.AccessEdge']$"),
("WebConfEdge" ,"$MPElement[Name='Microsoft.LS.2013.Component.WebConfEdge']$"),
("AVEdge" ,"$MPElement[Name='Microsoft.LS.2013.Component.AVEdge']$"),
("AVAuthEdge" ,"$MPElement[Name='Microsoft.LS.2013.Component.AVAuthEdge']$"),
("XmppFederationProxy" ,"$MPElement[Name='Microsoft.LS.2013.Component.XmppFederationProxy']$")
);
"MediationServer"=
@(,
("MediationServer" ,"$MPElement[Name='Microsoft.LS.2013.Component.MediationServer']$")
);
"LegalInterceptService"=
@(,
("LegalInterceptService" ,"$MPElement[Name='Microsoft.LS.2013.Component.LegalInterceptService']$")
);
"LogRetentionService"=
@(,
("LogRetentionService" ,"$MPElement[Name='Microsoft.LS.2013.Component.LogRetentionService']$")
);
"OcsCore"=
@(
("CMSReplicator" ,"$MPElement[Name='Microsoft.LS.2013.Component.CMSReplicator']$"),
("ClsAgent" ,"$MPElement[Name='Microsoft.LS.2013.Component.ClsAgent']$")
);
"Registrar"=
@(
("Registrar" ,"$MPElement[Name='Microsoft.LS.2013.Component.Registrar']$"),
("XmppFederation" ,"$MPElement[Name='Microsoft.LS.2013.Component.XmppFederation']$"),
("Lyss" ,"$MPElement[Name='Microsoft.LS.2013.Component.Lyss']$")
);
"ProvisionService"=
@(,
("ProvisionService" ,"$MPElement[Name='Microsoft.LS.2013.Component.ProvisionService']$")
);
"UserServices"=
@(
("MCUFactory" ,"$MPElement[Name='Microsoft.LS.2013.Component.MCUFactory']$"),
("PresenceFocus" ,"$MPElement[Name='Microsoft.LS.2013.Component.PresenceFocus']$")
);
"WebServices"=
@(
("ABHandler" ,"$MPElement[Name='Microsoft.LS.2013.Component.ABHandler']$"),
("AutodiscoverService" ,"$MPElement[Name='Microsoft.LS.2013.Component.AutodiscoverService']$"),
("DLExpansion" ,"$MPElement[Name='Microsoft.LS.2013.Component.DLExpansion']$"),
("CAHandler" ,"$MPElement[Name='Microsoft.LS.2013.Component.CAHandler']$"),
("HostedMigrationService" ,"$MPElement[Name='Microsoft.LS.2013.Component.HostedMigrationService']$"),
("TenantAdmin" ,"$MPElement[Name='Microsoft.LS.2013.Component.TenantAdmin']$"),
("Lwa" ,"$MPElement[Name='Microsoft.LS.2013.Component.Lwa']$"),
("LIService" ,"$MPElement[Name='Microsoft.LS.2013.Component.LIService']$"),
("McxService" ,"$MPElement[Name='Microsoft.LS.2013.Component.McxService']$"),
("RemotePowerShell" ,"$MPElement[Name='Microsoft.LS.2013.Component.RemotePowerShell']$"),
("StoreWeb" ,"$MPElement[Name='Microsoft.LS.2013.Component.StoreWeb']$"),
("UpdateServer" ,"$MPElement[Name='Microsoft.LS.2013.Component.UpdateServer']$"),
("UcwaService" ,"$MPElement[Name='Microsoft.LS.2013.Component.UcwaService']$"),
("WebInfra" ,"$MPElement[Name='Microsoft.LS.2013.Component.WebInfra']$"),
("Reach" ,"$MPElement[Name='Microsoft.LS.2013.Component.Reach']$"),
("WebScheduler" ,"$MPElement[Name='Microsoft.LS.2013.Component.WebScheduler']$")
);
"ApplicationServer"=
@(
("CAA" ,"$MPElement[Name='Microsoft.LS.2013.Component.CAA']$"),
("CAS" ,"$MPElement[Name='Microsoft.LS.2013.Component.CAS']$"),
("RGS" ,"$MPElement[Name='Microsoft.LS.2013.Component.RGS']$"),
("PDP" ,"$MPElement[Name='Microsoft.LS.2013.Component.PDP']$"),
("CPS" ,"$MPElement[Name='Microsoft.LS.2013.Component.CPS']$"),
("PNCH" ,"$MPElement[Name='Microsoft.LS.2013.Component.PNCH']$")
);
"BackupService"=
@(,
("BackupService" ,"$MPElement[Name='Microsoft.LS.2013.Component.BackupService']$")
);
"PersistentChatService"=
@(
("PersistentChat" ,"$MPElement[Name='Microsoft.LS.2013.Component.PersistentChat']$"),
("PersistentChatCompliance" ,"$MPElement[Name='Microsoft.LS.2013.Component.PersistentChatCompliance']$")
);
"BIDataCollectorService"=
@(,
("BIDataCollectorService" ,"$MPElement[Name='Microsoft.LS.2013.Component.BIDataCollectorService']$")
);
}

$componentRoleMaping =
@{
"CommonHostsCommon" = "$MPElement[Name='Microsoft.LS.2013.Relationship.CommonServiceHostsCommon']$";
"CentralMgmtHostsCMSFileTransfer" = "$MPElement[Name='Microsoft.LS.2013.Relationship.CentralMgmtHostsCMSFileTransfer']$";
"CentralMgmtHostsCMSMaster" = "$MPElement[Name='Microsoft.LS.2013.Relationship.CentralMgmtHostsCMSMaster']$";
"ConfServicesHostsIMConf" = "$MPElement[Name='Microsoft.LS.2013.Relationship.ConfServicesHostsIMConf']$";
"ConfServicesHostsPhoneConf" = "$MPElement[Name='Microsoft.LS.2013.Relationship.ConfServicesHostsPhoneConf']$";
"ConfServicesHostsAppSharingConf" = "$MPElement[Name='Microsoft.LS.2013.Relationship.ConfServicesHostsAppSharingConf']$";
"ConfServicesHostsAVConf" = "$MPElement[Name='Microsoft.LS.2013.Relationship.ConfServicesHostsAVConf']$";
"ConfServicesHostsDataConf" = "$MPElement[Name='Microsoft.LS.2013.Relationship.ConfServicesHostsDataConf']$";
"EdgeServerHostsAccessEdge" = "$MPElement[Name='Microsoft.LS.2013.Relationship.EdgeServerHostsAccessEdge']$";
"EdgeServerHostsWebConfEdge" = "$MPElement[Name='Microsoft.LS.2013.Relationship.EdgeServerHostsWebConfEdge']$";
"EdgeServerHostsAVEdge" = "$MPElement[Name='Microsoft.LS.2013.Relationship.EdgeServerHostsAVEdge']$";
"EdgeServerHostsAVAuthEdge" = "$MPElement[Name='Microsoft.LS.2013.Relationship.EdgeServerHostsAVAuthEdge']$";
"EdgeServerHostsXmppFederationProxy" = "$MPElement[Name='Microsoft.LS.2013.Relationship.EdgeServerHostsXmppFederationProxy']$";
"MediationServerHostsMediationServer" = "$MPElement[Name='Microsoft.LS.2013.Relationship.MediationServerHostsMediationServer']$";
"LegalInterceptServiceHostsLegalInterceptService" = "$MPElement[Name='Microsoft.LS.2013.Relationship.LegalInterceptServiceHostsLegalInterceptService']$";
"LogRetentionServiceHostsLogRetentionService" = "$MPElement[Name='Microsoft.LS.2013.Relationship.LogRetentionServiceHostsLogRetentionService']$";
"OcsCoreHostsCMSReplicator" = "$MPElement[Name='Microsoft.LS.2013.Relationship.OcsCoreHostsCMSReplicator']$";
"OcsCoreHostsClsAgent" = "$MPElement[Name='Microsoft.LS.2013.Relationship.OcsCoreHostsClsAgent']$";
"RegistrarHostsRegistrar" = "$MPElement[Name='Microsoft.LS.2013.Relationship.RegistrarHostsRegistrar']$";
"RegistrarHostsXmppFederation" = "$MPElement[Name='Microsoft.LS.2013.Relationship.RegistrarHostsXmppFederation']$";
"RegistrarHostsLyss" = "$MPElement[Name='Microsoft.LS.2013.Relationship.RegistrarHostsLyss']$";
"ProvisionServiceHostsProvisionService" = "$MPElement[Name='Microsoft.LS.2013.Relationship.ProvisionServiceHostsProvisionService']$";
"UserServicesHostsMCUFactory" = "$MPElement[Name='Microsoft.LS.2013.Relationship.UserServicesHostsMCUFactory']$";
"UserServicesHostsPresenceFocus" = "$MPElement[Name='Microsoft.LS.2013.Relationship.UserServicesHostsPresenceFocus']$";
"WebServicesHostsABHandler" = "$MPElement[Name='Microsoft.LS.2013.Relationship.WebServicesHostsABHandler']$";
"WebServicesHostsAutodiscoverService" = "$MPElement[Name='Microsoft.LS.2013.Relationship.WebServicesHostsAutodiscoverService']$";
"WebServicesHostsDLExpansion" = "$MPElement[Name='Microsoft.LS.2013.Relationship.WebServicesHostsDLExpansion']$";
"WebServicesHostsCAHandler" = "$MPElement[Name='Microsoft.LS.2013.Relationship.WebServicesHostsCAHandler']$";
"WebServicesHostsHostedMigrationService"= "$MPElement[Name='Microsoft.LS.2013.Relationship.WebServicesHostsHostedMigrationService']$";
"WebServicesHostsTenantAdmin" = "$MPElement[Name='Microsoft.LS.2013.Relationship.WebServicesHostsTenantAdmin']$";
"WebServicesHostsLwa" = "$MPElement[Name='Microsoft.LS.2013.Relationship.WebServicesHostsLwa']$";
"WebServicesHostsLIService" = "$MPElement[Name='Microsoft.LS.2013.Relationship.WebServicesHostsLIService']$";
"WebServicesHostsMcxService" = "$MPElement[Name='Microsoft.LS.2013.Relationship.WebServicesHostsMcxService']$";
"WebServicesHostsRemotePowerShell" = "$MPElement[Name='Microsoft.LS.2013.Relationship.WebServicesHostsRemotePowerShell']$";
"WebServicesHostsStoreWeb" = "$MPElement[Name='Microsoft.LS.2013.Relationship.WebServicesHostsStoreWeb']$";
"WebServicesHostsUpdateServer" = "$MPElement[Name='Microsoft.LS.2013.Relationship.WebServicesHostsUpdateServer']$";
"WebServicesHostsUcwaService" = "$MPElement[Name='Microsoft.LS.2013.Relationship.WebServicesHostsUcwaService']$";
"WebServicesHostsWebInfra" = "$MPElement[Name='Microsoft.LS.2013.Relationship.WebServicesHostsWebInfra']$";
"WebServicesHostsReach" = "$MPElement[Name='Microsoft.LS.2013.Relationship.WebServicesHostsReach']$";
"WebServicesHostsWebScheduler" = "$MPElement[Name='Microsoft.LS.2013.Relationship.WebServicesHostsWebScheduler']$";
"ApplicationServerHostsCAA" = "$MPElement[Name='Microsoft.LS.2013.Relationship.ApplicationServerHostsCAA']$";
"ApplicationServerHostsCAS" = "$MPElement[Name='Microsoft.LS.2013.Relationship.ApplicationServerHostsCAS']$";
"ApplicationServerHostsRGS" = "$MPElement[Name='Microsoft.LS.2013.Relationship.ApplicationServerHostsRGS']$";
"ApplicationServerHostsPDP" = "$MPElement[Name='Microsoft.LS.2013.Relationship.ApplicationServerHostsPDP']$";
"ApplicationServerHostsCPS" = "$MPElement[Name='Microsoft.LS.2013.Relationship.ApplicationServerHostsCPS']$";
"ApplicationServerHostsPNCH" = "$MPElement[Name='Microsoft.LS.2013.Relationship.ApplicationServerHostsPNCH']$";
"BackupServiceHostsBackupService" = "$MPElement[Name='Microsoft.LS.2013.Relationship.BackupServiceHostsBackupService']$";
"PersistentChatServiceHostsPersistentChat" = "$MPElement[Name='Microsoft.LS.2013.Relationship.PersistentChatServiceHostsPersistentChat']$";
"PersistentChatServiceHostsPersistentChatCompliance" = "$MPElement[Name='Microsoft.LS.2013.Relationship.PersistentChatServiceHostsPersistentChatCompliance']$";
"BIDataCollectorServiceHostsBIDataCollectorService" = "$MPElement[Name='Microsoft.LS.2013.Relationship.BIDataCollectorServiceHostsBIDataCollectorService']$";
}

$poolContainmentRelationShip =
@{
"Common"= "$MPElement[Name='Microsoft.LS.2013.Relationship.PoolContainsCommonService']$";
"CentralMgmt"= "$MPElement[Name='Microsoft.LS.2013.Relationship.PoolContainsCentralMgmt']$";
"ConfServices"= "$MPElement[Name='Microsoft.LS.2013.Relationship.PoolContainsConfServices']$";
"EdgeServer"= "$MPElement[Name='Microsoft.LS.2013.Relationship.PoolContainsEdgeServer']$";
"MediationServer"= "$MPElement[Name='Microsoft.LS.2013.Relationship.PoolContainsMediationServer']$";
"LegalInterceptService"= "$MPElement[Name='Microsoft.LS.2013.Relationship.PoolContainsLegalInterceptService']$";
"LogRetentionService"= "$MPElement[Name='Microsoft.LS.2013.Relationship.PoolContainsLogRetentionService']$";
"OcsCore"= "$MPElement[Name='Microsoft.LS.2013.Relationship.PoolContainsOcsCore']$";
"Registrar"= "$MPElement[Name='Microsoft.LS.2013.Relationship.PoolContainsRegistrar']$";
"ProvisionService"= "$MPElement[Name='Microsoft.LS.2013.Relationship.PoolContainsProvisionService']$";
"UserServices"= "$MPElement[Name='Microsoft.LS.2013.Relationship.PoolContainsUserServices']$";
"WebServices"= "$MPElement[Name='Microsoft.LS.2013.Relationship.PoolContainsWebServices']$";
"ApplicationServer"= "$MPElement[Name='Microsoft.LS.2013.Relationship.PoolContainsApplicationServer']$";
"BackupService"= "$MPElement[Name='Microsoft.LS.2013.Relationship.PoolContainsBackupService']$";
"PersistentChatService"= "$MPElement[Name='Microsoft.LS.2013.Relationship.PoolContainsPersistentChatService']$";
"BIDataCollectorService"= "$MPElement[Name='Microsoft.LS.2013.Relationship.PoolContainsBIDataCollectorService']$";
}

$MachineHostsServiceMap =
@{
"Common"= "$MPElement[Name='Microsoft.LS.2013.Relationship.ServerRoleHostsCommonService']$";
"CentralMgmt"= "$MPElement[Name='Microsoft.LS.2013.Relationship.ServerRoleHostsCentralMgmt']$";
"ConfServices"= "$MPElement[Name='Microsoft.LS.2013.Relationship.ServerRoleHostsConfServices']$";
"EdgeServer"= "$MPElement[Name='Microsoft.LS.2013.Relationship.ServerRoleHostsEdgeServer']$";
"MediationServer"= "$MPElement[Name='Microsoft.LS.2013.Relationship.ServerRoleHostsMediationServer']$";
"LegalInterceptService"= "$MPElement[Name='Microsoft.LS.2013.Relationship.ServerRoleHostsLegalInterceptService']$";
"LogRetentionService"= "$MPElement[Name='Microsoft.LS.2013.Relationship.ServerRoleHostsLogRetentionService']$";
"OcsCore"= "$MPElement[Name='Microsoft.LS.2013.Relationship.ServerRoleHostsOcsCore']$";
"Registrar"= "$MPElement[Name='Microsoft.LS.2013.Relationship.ServerRoleHostsRegistrar']$";
"ProvisionService"= "$MPElement[Name='Microsoft.LS.2013.Relationship.ServerRoleHostsProvisionService']$";
"UserServices"= "$MPElement[Name='Microsoft.LS.2013.Relationship.ServerRoleHostsUserServices']$";
"WebServices"= "$MPElement[Name='Microsoft.LS.2013.Relationship.ServerRoleHostsWebServices']$";
"ApplicationServer"= "$MPElement[Name='Microsoft.LS.2013.Relationship.ServerRoleHostsApplicationServer']$";
"BackupService"= "$MPElement[Name='Microsoft.LS.2013.Relationship.ServerRoleHostsBackupService']$";
"PersistentChatService"= "$MPElement[Name='Microsoft.LS.2013.Relationship.ServerRoleHostsPersistentChatService']$";
"BIDataCollectorService"= "$MPElement[Name='Microsoft.LS.2013.Relationship.ServerRoleHostsBIDataCollectorService']$";
}

$roleDisplayNameFormat = "LS {0} Service [{1}]"
$componentDisplayNameFormat = "LS {0} Component [{1}]"
$componentDisplayName =
@{
"Common" = "Common";
"CMSFileTransfer" = "Central Management File Transfer Agent";
"CMSMaster" = "Central Management Master Agent";
"IMConf" = "Instant Message Conferencing";
"PhoneConf" = "Audio Conferencing Provider";
"AppSharingConf" = "Application Sharing";
"AVConf" = "Audio Video Conferencing";
"DataConf" = "Data Conferencing";
"AccessEdge" = "Access Edge";
"WebConfEdge" = "Web Conferencing Edge";
"AVEdge" = "Audio Video Edge";
"AVAuthEdge" = "Audio Video Authentication Edge";
"MediationServer" = "Mediation Server";
"LegalInterceptService" = "Legal Intercept";
"LogRetentionService" = "Log Retention";
"CDR" = "Call Details Reporting";
"QOE" = "QoE";
"SquidReplicator" = "Replication Agent";
"Registrar" = "Registrar";
"ProvisionService" = "Provisioning";
"MCUFactory" = "MCU Factory";
"PresenceFocus" = "Presence Focus";
"ABHandler" = "Address Book File Handler";
"AutodiscoverService" = "Autodiscover Service";
"DLExpansion" = "Address Book Web Query And Expand Distribution List";
"CAHandler" = "Certificate Provisioning";
"HostedMigrationService" = "Hosted User Migration Service";
"TenantAdmin" = "Administration Center";
"Lwa" = "Join Launcher";
"LIService" = "Location Information";
"McxService" = "Mobile Communication Service";
"RemotePowerShell" = "PowerShell Server";
"StoreWeb" = "Storage Service Web";
"UpdateServer" = "Device Update Server";
"UcwaService" = "Unified Communications Web API";
"WebInfra" = "Web Infrastructure";
"Reach" = "Communicator Web App";
"WebScheduler" = "Web Scheduler";
"CAA" = "Conferencing Auto Attendant";
"CAS" = "Conferencing Announcement Service";
"RGS" = "Response Group";
"PDP" = "Policy Decision Point";
"CPS" = "Call Park Service";
"PNCH" = "Push Notification Clearing House Service";
"BackupService" = "Backup Service";
"PersistentChat" = "Persistent Chat";
"PersistentChatCompliance"= "Persistent Chat Compliance";
"ClsAgent" = "Centralized Logging Agent";
"XmppFederation" = "Xmpp Federation Service";
"XmppFederationProxy" = "Xmpp Federation Proxy Service";
"Lyss" = "Storage Service";
"BIDataCollectorService" = "BI Data Collector Service";
}

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

#HELPER FUNCTIONS############################################################
function IsDiscoverableComponent($cluster, $roleId, $componentId)
{
# Need a one-off special casing for ConfServices role.
# This is because we cannot guarantee that all the MCU components will be present in a deployment.
# We need to add only those MCUs that are installed.
if($roleId -eq [Microsoft.Rtc.Management.Core.RoleName]::ConfServices)
{
$ConfServicesService = $cluster.InstalledServices[[Microsoft.Rtc.Management.Core.RoleName]::ConfServices]
$mcus = $ConfServicesService.MCUs;

# The below syntax essentially walks the $ConfServicesService object[] and extracts the
# LocalName field into a string array so that we can run a -notcontains operator.
if(($mcus | foreach-object {$_.ComponentId.LocalName}) -notcontains $componentId)
{
# This component (i.e application) is not enabled.
# so ignore adding it to the DiscoveryData
$false
return
}
}

# Need a one-off special casing for ApplicationsServer role.
# This is because they have been modeled as applications
# and not all apps can be enabled on a given ApplicationServer role.
if($roleId -eq [Microsoft.Rtc.Management.Core.RoleName]::ApplicationServer)
{
$applicationServerService = $cluster.InstalledServices[[Microsoft.Rtc.Management.Core.RoleName]::ApplicationServer]
$applications = $applicationServerService.Applications;

# The below syntax essentially walks the $applications object[] and extracts the
# LocalName field into a string array so that we can run a -notcontains operator.
if(($applications | foreach-object {$_.LocalName}) -notcontains $componentId)
{
# This component (i.e application) is not enabled.
# so ignore adding it to the DiscoveryData
$false
return
}
}

# Need a one-off special casing for PersistentChat role.
# Rule 1:
# This is because of PersistentChatCompliance. if ComplianceStore is not installed, then we should not discover PersistentChatCompliance.
# Rule 2:
# Check whether local fqdn is in active Fqdn list.
if($roleId -eq [Microsoft.Rtc.Management.Core.RoleName]::PersistentChatService)
{
$persistentChatService = $cluster.InstalledServices[[Microsoft.Rtc.Management.Core.RoleName]::PersistentChatService]
$persistentChatComplianceStoreRoleName = [Microsoft.Rtc.Management.Core.RoleName]::PersistentChatComplianceStore
$defaultUsage = [Microsoft.Rtc.Management.Deploy.DependencyUsage]::Default
$dependencyId = [Microsoft.Rtc.Management.Deploy.DependencyId]::Get($persistentChatComplianceStoreRoleName, $defaultUsage)
if ($persistentChatService.DependentServices[$dependencyId] -eq $null)
{
# Rule 1:
# This component (i.e PersistentChatCompliance) is not enabled, because PersistentChatComplianceStore dependency does not exist.
# so ignore adding it to the DiscoveryData
if ($componentId -eq "PersistentChatCompliance")
{
$false
return
}
}
else
{
# Rule 2:
# If the current machine is not in active fqdns' list, then ignore discovery of persistent chat server.
if ($persistentChatService.ActiveServers -notcontains $targetComputer)
{
$false
return
}
}
}

# Need a one-off special casing for WebServices role.
# This is because we cannot guarantee that all the Web components will be present in a deployment.
# We need to add only those web components that are installed.
if($roleId -eq [Microsoft.Rtc.Management.Core.RoleName]::WebServices)
{
# Common Component for Web Services.
if ($componentId -eq "WebInfra")
{
$true
return
}

$WebServicesService = $cluster.InstalledServices[[Microsoft.Rtc.Management.Core.RoleName]::WebServices]
$webComponentList = $WebServicesService.GetEnabledVirtualDirs() | % {$_.VirtualDirId.ComponentId.LocalName} | select-object -Unique

# The below syntax essentially walks the $webComponentList object[] and extracts the
# LocalName field into a string array so that we can run a -notcontains operator.
if($webComponentList -notcontains $componentId)
{
# This web component is not enabled.
# so ignore adding it to the DiscoveryData
$false
return
}
}

# Need a one-off special casing for Registrar role.
# This is because; XmppFederation component only deployed if XmppFederation port is in registrar role.
if (($roleId -eq [Microsoft.Rtc.Management.Core.RoleName]::Registrar) -and ($componentId -eq "XmppFederation"))
{
$registrarService = $cluster.InstalledServices[[Microsoft.Rtc.Management.Core.RoleName]::Registrar]
$ports = $registrarService.NetPorts
$filteredPorts = @( $ports | where { ($_.NetPortId.Owner -eq [Microsoft.Rtc.Management.Core.ComponentId]::XmppFederation) -and ($_.Enabled -eq $true)} )
if ($filteredPorts.Count -eq 0)
{
# This XmppFederation is not present or enabled.
# so ignore adding it to the DiscoveryData
$false
return
}
}

# Need a one-off special casing for Edge Server role.
# This is because; XmppFederationProxy component only deployed if XmppFederationProxy port is in Edge Server role.
if (($roleId -eq [Microsoft.Rtc.Management.Core.RoleName]::EdgeServer) -and ($componentId -eq "XmppFederationProxy"))
{
$edgeServer = $cluster.InstalledServices[[Microsoft.Rtc.Management.Core.RoleName]::EdgeServer]
$ports = $edgeServer.NetPorts
$filteredPorts = @( $ports | where { ($_.NetPortId.Owner -eq [Microsoft.Rtc.Management.Core.ComponentId]::XmppFederationProxy) -and ($_.Enabled -eq $true)} )
if ($filteredPorts.Count -eq 0)
{
# This XmppFederationProxy is not present or enabled.
# so ignore adding it to the DiscoveryData
$false
return
}
}

$true
return
}

#############################################################################
# 1. Prepare discovery data
$DiscoveryData = GetDiscoveryData
TRACE ("Successfully initialize discovery data.");

# 2. Find Current machine
$currentMachineFqdn = $TargetComputer
# Local machine discovery requires only access to local topology data.
$topology = Get-CsTopology -LocalStore
$currentMachine = $topology.Machines | where {$_.Fqdn -eq $currentMachineFqdn}
if (!$currentMachine)
{
throw "Current machine {0} does not exist in the topology." -f $currentMachineFqdn
}
TRACE ("Successfully found current machine in topology. Machine Fqdn is {0}" -f $currentMachineFqdn);

# 3 Discover Deployment
$deployment = $DiscoveryData.CreateClassInstance("$MPElement[Name='Microsoft.LS.2013.Deployment']$");
TRACE ("Successfully discover deployment");

# 4. Discover Site
$site = $currentMachine.Cluster.Site
$IsDiscoverableSite = IsDiscoverableSite($site)
if ($IsDiscoverableSite -eq $false)
{
throw "Current machine {0} is not in discoverable site." -f $currentMachineFqdn
}

$ocsSite = $DiscoveryData.CreateClassInstance("$MPElement[Name='Microsoft.LS.2013.Site']$");
$ocsSite.AddProperty("$MPElement[Name='Microsoft.LS.2013.Site']/SiteName$", $site.Name);
$ocsSite.AddProperty("$MPElement[Name='Microsoft.LS.2013.Site']/SiteType$", $site.Kind.ToString());
$ocsSite.AddProperty("$MPElement[Name="System!System.Entity"]/DisplayName$", $site.Name);
$DiscoveryData.AddInstance($ocsSite);

$deploymentContainsSite = $DiscoveryData.CreateRelationshipInstance("$MPElement[Name='Microsoft.LS.2013.Relationship.DeploymentContainsSite']$");
$deploymentContainsSite.Source = $deployment
$deploymentContainsSite.Target = $ocsSite
$DiscoveryData.AddInstance($deploymentContainsSite);
TRACE ($DISCOVERY_SUCCESS -f "LS Site", $site.Name);

# 5. Discover Pool [Cluster]
$ClustersRequireSetup = @(GetClustersRequireSetup $site)
$cluster = $ClustersRequireSetup | where {$_.Fqdn -eq $currentMachine.Cluster.Fqdn}
if (!$cluster)
{
throw "Cluster of current machine {0} does not require setup. Skipping discovery." -f $currentMachineFqdn
}

$clusterFqdn = $cluster.Fqdn.ToString()
$clusterType = (GetClusterType $cluster)

$ocsCluster = $DiscoveryData.CreateClassInstance("$MPElement[Name='Microsoft.LS.2013.Cluster']$");
$ocsCluster.AddProperty("$MPElement[Name='Microsoft.LS.2013.Cluster']/PoolFqdn$", $clusterFqdn);
$ocsCluster.AddProperty("$MPElement[Name='Microsoft.LS.2013.Cluster']/PoolType$", $clusterType + " Pool");
$ocsCluster.AddProperty("$MPElement[Name='Microsoft.LS.2013.Cluster']/SiteName$", $site.Name);
$ocsCluster.AddProperty("$MPElement[Name="System!System.Entity"]/DisplayName$", ("{0} Pool [{1}]" -f $clusterType, $clusterFqdn));
$DiscoveryData.AddInstance($ocsCluster);

$siteContainsCluster = $DiscoveryData.CreateRelationshipInstance("$MPElement[Name='Microsoft.LS.2013.Relationship.SiteContainsClusters']$");
$siteContainsCluster.Source = $ocsSite
$siteContainsCluster.Target = $ocsCluster
$DiscoveryData.AddInstance($siteContainsCluster);
TRACE ($DISCOVERY_SUCCESS -f "LS Pool", $clusterFqdn);

# 6. Discover Server Role
$machineType = ((GetClusterType $cluster) + " Machine")
$csMachine = $DiscoveryData.CreateClassInstance("$MPElement[Name='Microsoft.LS.2013.ServerRole']$");
$csMachine.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", $currentMachineFqdn);
$csMachine.AddProperty("$MPElement[Name='Microsoft.LS.2013.ServerRole']/ServerType$", $machineType);
$csMachine.AddProperty("$MPElement[Name='Microsoft.LS.2013.ServerRole']/PoolFqdn$", $cluster.Fqdn.ToString());
$csMachine.AddProperty("$MPElement[Name="System!System.Entity"]/DisplayName$", ("{0} Machine [{1}]" -f $machineType, $currentMachineFqdn));
$DiscoveryData.AddInstance($csMachine);
TRACE ($DISCOVERY_SUCCESS -f "LS Machine", $currentMachineFqdn)

# 7. Discover Services (Roles) E.g. Registrar, UserServices, ...
$roleIds = @(SupportedRolesForCluster $cluster)
if ($roleIds.Count -eq 0)
{
throw "Cluster of current machine {0} does not have any role supported." -f $currentMachineFqdn
}

# Special handling for OcsCore role.
# Squid cmdlet does not return OCSCore as a role.
# Discovery script needs to append this role regardless of query result from squid.
$roleIds += "OcsCore"
# Common Role is used to monitor common KHIs. E.g. Disk, Process.
$roleIds += "Common"

foreach ($roleId in $roleIds)
{
#Discover all the roles
#( A cluster can have multiple machines with same services installed - we call it Roles).
$machineFqdn = $currentMachineFqdn

$role = $DiscoveryData.CreateClassInstance($roleMap[$roleId]);
$role.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", $machineFqdn);
$role.AddProperty("$MPElement[Name="System!System.Entity"]/DisplayName$", ($roleDisplayNameFormat -f $roleDisplayName[$roleId], $machineFqdn));
$DiscoveryData.AddInstance($role);

$MachineHostsService =
$DiscoveryData.CreateRelationshipInstance($MachineHostsServiceMap[$roleId]);
$MachineHostsService.Source = $csMachine
$MachineHostsService.Target = $role
$DiscoveryData.AddInstance($MachineHostsService);

#Discover all the components that belong to this Role.
$components = @($componentMap[$roleId])
foreach ($component in $components)
{
$componentName = $component[0]
$componentClassId = $component[1]

if ((IsDiscoverableComponent $cluster $roleId $componentName) -eq $false)
{
continue
}

$ocsComponent = $DiscoveryData.CreateClassInstance($componentClassId);
$ocsComponent.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", $machineFqdn);
$ocsComponent.AddProperty("$MPElement[Name="System!System.Entity"]/DisplayName$", ($componentDisplayNameFormat -f $componentDisplayName[$componentName], $machineFqdn));
$DiscoveryData.AddInstance($ocsComponent);
TRACE ($DISCOVERY_SUCCESS -f "Component", $componentName)

$componentRoleMappingId = ($roleId + "Hosts" + $componentName)
$OCSRoleHostsOCSComponent =
$DiscoveryData.CreateRelationshipInstance($componentRoleMaping[$componentRoleMappingId]);
$OCSRoleHostsOCSComponent.Source = $role
$OCSRoleHostsOCSComponent.Target = $ocsComponent
$DiscoveryData.AddInstance($OCSRoleHostsOCSComponent);
TRACE ($DISCOVERY_SUCCESS -f "Relationship", $componentRoleMappingId)
}

$PoolContainsService =
$DiscoveryData.CreateRelationshipInstance($poolContainmentRelationShip[$roleId]);
$PoolContainsService.Source = $ocsCluster
$PoolContainsService.Target = $role
$DiscoveryData.AddInstance($PoolContainsService);

TRACE ($DISCOVERY_SUCCESS -f "Role", $roleId)
}
</Script></ScriptBody>
<TimeoutSeconds>$Config/TimeoutSeconds$</TimeoutSeconds>
<EventId>223</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>