SharePoint Application Discovery

Microsoft.Dynamics.Retail.AX2012.R2.FP.Base.Discovery.SharePointApplicationDiscovery (Discovery)

Discovers SharePoint application instances.

Knowledge Base article:

Summary

Discovers SharePoint application instances.

Element properties:

TargetMicrosoft.Windows.OperatingSystem
EnabledTrue
Frequency28800
RemotableFalse

Object Discovery Details:

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

Member Modules:

ID Module Type TypeId RunAs 
DataSource DataSource Microsoft.Windows.TimedPowerShell.DiscoveryProvider Default

Source Code:

<Discovery ID="Microsoft.Dynamics.Retail.AX2012.R2.FP.Base.Discovery.SharePointApplicationDiscovery" Enabled="true" Target="Windows!Microsoft.Windows.OperatingSystem" ConfirmDelivery="true" Remotable="false" Priority="Normal">
<Category>Discovery</Category>
<DiscoveryTypes>
<DiscoveryClass TypeID="Microsoft.Dynamics.Retail.AX2012.R2.FP.Base.Class.SharePointServer"/>
<DiscoveryClass TypeID="Microsoft.Dynamics.Retail.AX2012.R2.FP.Base.Class.SharePointTimerJob"/>
<DiscoveryClass TypeID="Microsoft.Dynamics.Retail.AX2012.R2.FP.Base.Class.SharePointWebApplication"/>
<DiscoveryRelationship TypeID="Microsoft.Dynamics.Retail.AX2012.R2.FP.Base.RelationShip.SharePointTimerJobToServer"/>
<DiscoveryRelationship TypeID="Microsoft.Dynamics.Retail.AX2012.R2.FP.Base.RelationShip.SharePointWebApplicationServerToComputer"/>
<DiscoveryRelationship TypeID="Microsoft.Dynamics.Retail.AX2012.R2.FP.Base.RelationShip.SharePointWebApplicationToServer"/>
</DiscoveryTypes>
<DataSource ID="DataSource" TypeID="Windows!Microsoft.Windows.TimedPowerShell.DiscoveryProvider">
<IntervalSeconds>28800</IntervalSeconds>
<SyncTime/>
<ScriptName>SharePointECommerceDiscovery.ps1</ScriptName>
<ScriptBody><Script>&lt;#
SAMPLE CODE NOTICE

THIS SAMPLE CODE IS MADE AVAILABLE AS IS. MICROSOFT MAKES NO WARRANTIES, WHETHER EXPRESS OR IMPLIED,
OF FITNESS FOR A PARTICULAR PURPOSE, OF ACCURACY OR COMPLETENESS OF RESPONSES, OF RESULTS, OR CONDITIONS OF MERCHANTABILITY.
THE ENTIRE RISK OF THE USE OR THE RESULTS FROM THE USE OF THIS SAMPLE CODE REMAINS WITH THE USER.
NO TECHNICAL SUPPORT IS PROVIDED. YOU MAY NOT DISTRIBUTE THIS CODE UNLESS YOU HAVE A LICENSE AGREEMENT WITH MICROSOFT THAT ALLOWS YOU TO DO SO.
#&gt;

param($target, $element, $computerName)
# this constant is used for logger initialization
$kScriptName = "SharePointECommerceDiscovery.ps1"
#Logging.psm1#

## Event codes
### RetailServerInstanceDiscovery
$kRetailServerInstanceDiscoveryStartedToRun = 10000
$kRetailServerInstanceDiscoveryRegistryKeyFound = 10001
$kRetailServerInstanceDiscoveryNewInstanceAddedToDiscoveryData = 10002
$kRetailServerInstanceDiscoveryNoRegistryKeyFound = 10003
$kRetailServerInstanceDiscoveryFinishedSuccessfully = 10004
$kRetailServerInstanceDiscoveryFinishedWithError = 10005

### RealtimeServiceInstanceDiscovery
$kRealtimeServiceInstanceDiscoveryStartedToRun = 10020
$kRealtimeServiceInstanceDiscoveryRegistryKeyFound = 10021
$kRealtimeServiceInstanceDiscoveryAddedToDiscoveryData = 10022
$kRealtimeServiceInstanceDiscoveryNoRegistryKeyFound = 10023
$kRealtimeServiceInstanceDiscoveryFinishedSuccessfully = 10024
$kRealtimeServiceInstanceDiscoveryFinishedWithError = 10025

### AsyncServerReplicationJobDiscovery
$kAsyncServerReplicationJobDiscoveryReplicationJobFound = 10050
$kAsyncServerReplicationJobDiscoveryNoReplicationJobsFound = 10051
$kAsyncServerReplicationJobDiscoveryNoEventWithReplicationJobs = 10052
$kAsyncServerReplicationJobDiscoveryStartedToRun = 10053
$kAsyncServerReplicationJobDiscoveryNoAOSInstancesFound = 10054
$kAsyncServerReplicationJobDiscoveryNoAOSRegistryKeysFound = 10055
$kAsyncServerReplicationJobDiscoveryFinishedSuccessfully = 10056
$kAsyncServerReplicationJobDiscoveryFinishedWithError = 10057
$kAsyncServerReplicationJobDiscoveryReplicationJobsEventId = 10065 # This event is generated by Dynamics Server

### SharePointECommerceDiscovery
$kSharePointECommerceDiscoveryStartedToRun = 10080
$kSharePointECommerceDiscoveryFinishedSuccessfully = 10081
$kSharePointECommerceDiscoveryFinishedWithError = 10082
$kSharePointECommerceDiscoveryFarmFound = 10083
$kSharePointECommerceDiscoveryFarmNotFound = 10084
$kSharePointECommerceDiscoveryECommerceDeploymentFound = 10085
$kSharePointECommerceDiscoveryECommerceDeploymentNotFound = 10086
$kSharePointECommerceDiscoveryECommerceWebAppsFound = 10087
$kSharePointECommerceDiscoveryECommerceWebAppsNotFound = 10088
$kSharePointECommerceDiscoveryECommerceTimerJobsFound = 10089
$kSharePointECommerceDiscoveryECommerceTimerJobsNotFound = 10090
$kSharePointECommerceDiscoveryECommerceWebAppDiscoveryDataAdded = 10091
$kSharePointECommerceDiscoveryECommerceTimerJobDiscoveryDataAdded = 10091

### CdxSynchServiceClientDiscovery
$kCdxSynchServiceClientDiscoveryStartedToRun = 10100
$kCdxSynchServiceClientDiscoveryRootKeyFound = 10101
$kCdxSynchServiceClientDiscoveryFailedToEvaluateErrorCountingPeriod = 10102
$kCdxSynchServiceClientDiscoveryNewInstanceDiscovered = 10103
$kCdxSynchServiceClientDiscoveryNoRootKeyFound = 10104
$kCdxSynchServiceClientDiscoveryFinishedSuccessfully = 10105
$kCdxSynchServiceClientDiscoveryFinishedWithError = 10106

### CdxSynchServiceServerDiscovery
$kCdxSynchServiceServerDiscoveryStartedToRun = 10110
$kCdxSynchServiceServerDiscoveryRootKeyFound = 10111
$kCdxSynchServiceServerDiscoveryNewInstanceDiscovered = 10112
$kCdxSynchServiceServerDiscoveryNoRootKeyFound = 10113
$kCdxSynchServiceServerDiscoveryFinishedSuccessfully = 10114
$kCdxSynchServiceServerDiscoveryFinishedWithError = 10115

### RetailServerChannelDBConnectionDiscovery
$kRetailServerChannelDBConnectionDiscoveryStartedToRun = 10120
$kRetailServerChannelDBConnectionDiscoverySearchingSuccessEvents = 10121
$kRetailServerChannelDBConnectionDiscoverySearchingErrorEvents = 10122
$kRetailServerChannelDBConnectionDiscoveryNewInstanceFound = 10123
$kRetailServerChannelDBConnectionDiscoveryNoInstancesFound = 10124
$kRetailServerChannelDBConnectionDiscoveryFinishedSuccessfully = 10125
$kRetailServerChannelDBConnectionDiscoveryFinishedWithError = 10126

### HardwareStationDiscovery
$kHardwareStationDiscoveryStartedToRun = 10140
$kHardwareStationDiscoveryRegistryKeyFound = 10141
$kHardwareStationDiscoveryNewInstanceAddedToDiscoveryData = 10142
$kHardwareStationDiscoveryNoRegistryKeyFound = 10143
$kHardwareStationDiscoveryFinishedSuccessfully = 10144
$kHardwareStationDiscoveryFinishedWithError = 10145

$kChannelDbConnectivityFailureEventId = 10200 # This event is generated by CRT Sdk (Retail Server, POS, eCommerce)
$kChannelDbConnectivitySuccessEventId = 10201 # This event is generated by CRT Sdk (Retail Server, POS, eCommerce)

### ReplicationJobScheduleState
$kReplicationJobStateStartedToRun = 10230
$kReplicationJobStateNoMonitoringEvents = 10231
$kReplicationJobStateSucceeded = 10232
$kReplicationJobStateFailed = 10233
$kReplicationJobStateFinishedSuccessfully = 10234
$kReplicationJobStateFinishedWithError = 10235

$kReplicationJobStateEventId = 10230 # This event is generated by Dynamics Server

### IISAppPoolStatus
$kIISAppPoolStatusStartedToRun = 10300
$kIISAppPoolStatusInetsrvNotExist = 10301
$kIISAppPoolStatusAppCmdDoesntExist = 10302
$kIISAppPoolStatusNoAppPoolName = 10303
$kIISAppPoolStatusAppcmdExitedWithError = 10304
$kIISAppPoolStatusUnexpectedAppcmdOutput = 10305
$kIISAppPoolStatusLogBagContent = 10306
$kIISAppPoolStatusFinishedSuccessfully = 10307
$kIISAppPoolStatusExitedWithError = 10308

### ConnectionToChannelDbState
$kConnectionToChannelDbStateStartedToRun = 10310
$kConnectionToChannelDbStateSearchingSuccessEvents = 10311
$kConnectionToChannelDbStateSearchingErrorEvents = 10312
$kConnectionToChannelDbStateNoMonitoringEvents = 10313
$kConnectionToChannelDbStateSuccess = 10314
$kConnectionToChannelDbStateFailed = 10315
$kConnectionToChannelDbStateFinishedSuccessfully = 10316
$kConnectionToChannelDbStateFinishedWithError = 10317

### HardwareStationSmokeTest
$kHardwareStationSmokeTestStartedToRun = 10320
$kHardwareStationSmokeTestFinishedSuccessfully = 10321
$kHardwareStationSmokeTestFinishedWithError = 10322

### ChangeTraceLevelInAppConfig
$kChangeTraceLevelInAppConfigStartedToRun = 10400
$kChangeTraceLevelInAppConfigFinishedSuccessfully = 10401
$kChangeTraceLevelInAppConfigFinishedWithError = 10402
$kChangeTraceLevelInAppConfigFileSaved = 10403
$kChangeTraceLevelInAppConfigFileUnchanged = 10404
$kChangeTraceLevelInAppConfigFileParameterCheckError = 10405

### ChangeSharePointTracingLevel
$kChangeSharePointTracingLevelStartedToRun = 10600
$kChangeSharePointTracingLevelFinishedSuccessfully = 10601
$kChangeSharePointTracingLevelFinishedWithError = 10602
$kChangeSharePointTracingLevelParameterCheckError = 10603

### EnterprisePosDiscovery
$kEnterprisePosDiscoveryStartedToRun = 10700
$kEnterprisePosDiscoveryFinishedSuccessfully = 10701
$kEnterprisePosDiscoveryFinishedWithError = 10702
$kNoEnterprisePosDiscoveryDataFound = 10703
$kEnterprisePosDiscoveryEvent = 10704

### EnterprisePosOfflineDiscovery
$kRetailPosOfflineServiceDiscoveryStartedToRun = 10800
$kNoRetailPosOfflineServiceDiscoveryDataFound = 10801
$kRetailPosOfflineServiceDiscoveryFinishedSuccessfully = 10802
$kRetailPosOfflineServiceDiscoveryRootKeyFound = 10803
$kRetailPosOfflineServiceDiscoveryNotUsedByPos = 10804
$kRetailPosOfflineServiceDiscoveryFinishedSuccessfully = 10805
$kNoRetailPosOfflineServiceAdditionalDiscoveryDataFound = 10806
$kRetailPosOfflineServiceDiscoveryFinishedSuccessfully = 10807
$kRetailPosOfflineServiceDiscoveryFinishedWithError = 10808

### StartAppPool
$kStartAppPoolStartedToRun = 10900
$kStartAppPoolFinishedSuccessfully = 10901
$kStartAppPoolFinishedWithError = 10902

### CertificateStatus
$kCertificateStatusStartedToRun = 10910
$kCertificateStatusNonExistingCertificate = 10911
$kCertificateStatusLogBagContent = 10912
$kCertificateStatusFinishedSuccessfully = 10913
$kCertificateStatusExitedWithError = 10914

### SetDiscoveryTimeFrame
$kSetDiscoveryTimeFrameStartedToRun = 10920
$kSetDiscoveryTimeFrameFinishedSuccessfully = 10921
$kSetDiscoveryTimeFrameFinishedWithError = 10922

## Functions
### Function tests if logging is enabled
function Test-LoggingEnabled
{
(Get-ItemProperty -Path $LoggingAbilityItemPath -ErrorAction SilentlyContinue).EnableMonitoringScriptLogging -eq "Enabled"
}

## Constants
$LoggingAbilityItemPath = "HKLM:\SOFTWARE\Microsoft\Dynamics\6.0"
$LoggingAbilityItemPropertyName = "EnableMonitoringScriptLogging"

$kLogWidth = 200 # characters
$kLogName = "Application"
$kLogSourceName = "Microsoft Dynamics AX Retail Monitoring"
$kEnableLogging = Test-LoggingEnabled

# This is needed to mock the logger object
if ($logger -ne $null)
{
# $logger object is initialized with the MS.Dynamics.Test.Retail.Test.Monitoring.Mocks.Logger object
$logger.LogName = $kLogName;
$logger.LogSourceName = $kLogSourceName;
$logger.ScriptName = $kScriptName;
}
else
{
# this means that object $logger is not initialized
## Create logger
$logger = New-Object -TypeName System.Management.Automation.PSObject

### Add logger properties
$logger | Add-Member -MemberType ScriptProperty -Name LogName -Value { $kLogName }
$logger | Add-Member -MemberType ScriptProperty -Name LogSourceName -Value { $kLogSourceName }
$logger | Add-Member -MemberType ScriptProperty -Name ScriptName -Value { $kScriptName }
$logger | Add-Member -MemberType ScriptProperty -Name ShouldWriteToEventLog -Value { $kEnableLogging }

### Add logger methods
$logger | Add-Member -MemberType ScriptMethod -Name LogInfo -Value {
param($eventId, $message)
if ($This.ShouldWriteToEventLog)
{
try
{
Write-EventLog -LogName $This.LogName -Source $This.LogSourceName -EntryType Information -EventId $eventId -Message ($This.ScriptName + " : " + $message) -ErrorAction Stop
}
catch
{
try
{
$scomApi.LogScriptEvent($This.ScriptName, $eventId, 0, "{0}" -f $message)
}
catch
{
}
}
}
}

$logger | Add-Member -MemberType ScriptMethod -Name LogError -Value {
param($eventId, $message)
try
{
Write-EventLog -LogName $This.LogName -Source $This.LogSourceName -EntryType Error -EventId $eventId -Message ($This.ScriptName + " : " + $message) -ErrorAction Stop
}
catch
{
try
{
$scomApi.LogScriptEvent($This.ScriptName, $eventId, 2, "{0}" -f $message)
}
catch
{
}
}
}

$logger | Add-Member -MemberType ScriptMethod -Name LogScriptExecutionSucceeded -Value {
param($eventId)
$This.LogInfo($eventId, "Script execution ended successfully")
}

$logger | Add-Member -MemberType ScriptMethod -Name LogScriptExecFailed -Value {
param($eventId, $error)
$This.LogError($eventId, "Script executed with errors :`n" + ($error | Out-String -Width $kLogWidth))
}

$logger | Add-Member -MemberType ScriptMethod -Name LogScriptExecFailedWithDefaultError -Value {
param($eventId)
$This.LogError($eventId, "Script executed with errors :`n" + ($Global:Error | Out-String -Width $kLogWidth))
}
}

#ScomApi.psm1#

## Create SCOM Api Object
# needed for mocking
if ($scomApi -ne $null)
{
# scomApi is created by wrapper test case
}
else
{
$scomApi = New-Object -ComObject 'MOM.ScriptAPI' -ErrorAction SilentlyContinue
if ($scomApi -eq $null) {
return $null
}
}

# Run Discovery Script
$logger.LogInfo($kSharePointECommerceDiscoveryStartedToRun, ("Running on machine {0}. Element: {1} Target: {2}" -f $computerName, $element, $target))
try
{
$discoveryData = $scomApi.CreateDiscoveryData(0, $element, $target)

[bool]$isSPFarm = $false
[bool]$isECommerceSPFarm = $false
$farmSharePointRegKeyPath = "HKLM:\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\15.0\Secure\ConfigDB\"
$farmECommerceRegKeyPath = "HKLM:\SOFTWARE\Microsoft\Dynamics\6.0\eCommerce\Farm\"

# 1. Test if we are on a SharePoint machine with a farm
if((Test-Path $farmSharePointRegKeyPath) -and ((Get-Item $farmSharePointRegKeyPath).GetValue("Id") -ne $null))
{
$isSPFarm = $true
$logger.LogInfo($kSharePointECommerceDiscoveryFarmFound, "Found server to be part of a SharePoint farm.")
}
else
{
$logger.LogInfo($kSharePointECommerceDiscoveryFarmNotFound, "Did not find a SharePoint farm. Discovery will end on this server.")
}

# 2. Test if our reg keys are there
if($isSPFarm -eq $true)
{
if((Test-Path $farmECommerceRegKeyPath) -and ((Get-Item $farmECommerceRegKeyPath).GetValue("Id") -ne $null))
{
$farmIdString = (Get-Item $farmECommerceRegKeyPath).GetValue("Id")
$isECommerceSPFarm = $true
$farmIdGuid = [GUID]$farmIdString
$logger.LogInfo($kSharePointECommerceDiscoveryECommerceDeploymentFound, ("Found server to be part of a Dynamics ECommerce deployment. Farm ID is {0}." -f $farmIdString))
}
else
{
$logger.LogInfo($kSharePointECommerceDiscoveryECommerceDeploymentNotFound, "Found server not to be part of a Dynamics ECommerce deployment. Discovery will end on this server.")
}

# 3. Get web apps
if($isECommerceSPFarm -eq $true)
{
$webAppKeyPath = $farmECommerceRegKeyPath + "WebApps"
if(Test-Path $webAppKeyPath)
{
$logger.LogInfo($kSharePointECommerceDiscoveryECommerceWebAppsFound, "Found Dynamics ECommerce web applications deployed.")
Get-ChildItem $webAppKeyPath | % {
$webAppName = $_.PSChildName
$webAppUrl = $_.GetValue("Url")
$webAppPublisherName = $_.GetValue("PublisherName")
$webAppPublisherNameMonitoring = $_.GetValue("PublisherNameMonitoring")

$serverInstance = $discoveryData.CreateClassInstance("$MPElement[Name='Microsoft.Dynamics.Retail.AX2012.R2.FP.Base.Class.SharePointServer']$")
$serverInstance.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", [string]($computerName))
# ID must be unique, so the rule does not get cooked down
$uniqueId = ("{0} - {1}" -f [string]($computerName), $webAppPublisherName)
$serverInstance.AddProperty("$MPElement[Name='Microsoft.Dynamics.Retail.AX2012.R2.FP.Base.Class.SharePointServer']/ID$", [string]($uniqueId))
$serverInstance.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", [string]$computerName)
$serverInstance.AddProperty("$MPElement[Name='Microsoft.Dynamics.Retail.AX2012.R2.FP.Base.Class.SharePointServer']/FarmID$", [string]($farmIdGuid.ToString()))
$serverInstance.AddProperty("$MPElement[Name='Microsoft.Dynamics.Retail.AX2012.R2.FP.Base.Class.SharePointServer']/PublisherName$", [string]($webAppPublisherName))
$serverInstance.AddProperty("$MPElement[Name='Microsoft.Dynamics.Retail.AX2012.R2.FP.Base.Class.SharePointServer']/PublisherNameMonitoring$", [string]($webAppPublisherNameMonitoring))
$discoveryData.AddInstance($serverInstance)

$appInstance = $discoveryData.CreateClassInstance("$MPElement[Name='Microsoft.Dynamics.Retail.AX2012.R2.FP.Base.Class.SharePointWebApplication']$")

$appInstance.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", [string]($webAppName))
# ID must be unique in order for it to be aggreated. If we monitor 2 farms with the same objects, we would roll them up into one SCOM instance, hence we use farm id here as well
$uniqueId = ("{0} - {1}" -f $farmIdGuid.ToString(), $webAppName)
$appInstance.AddProperty("$MPElement[Name='Microsoft.Dynamics.Retail.AX2012.R2.FP.Base.Class.SharePointWebApplication']/ID$", [string]($uniqueId))
$appInstance.AddProperty("$MPElement[Name='Microsoft.Dynamics.Retail.AX2012.R2.FP.Base.Class.SharePointWebApplication']/Name$", [string]($webAppName))
$appInstance.AddProperty("$MPElement[Name='Microsoft.Dynamics.Retail.AX2012.R2.FP.Base.Class.SharePointWebApplication']/FarmID$", [string]($farmIdGuid.ToString()))
$appInstance.AddProperty("$MPElement[Name='Microsoft.Dynamics.Retail.AX2012.R2.FP.Base.Class.SharePointWebApplication']/PublisherName$", [string]($webAppPublisherName))
$appInstance.AddProperty("$MPElement[Name='Microsoft.Dynamics.Retail.AX2012.R2.FP.Base.Class.SharePointWebApplication']/PublisherNameMonitoring$", [string]($webAppPublisherNameMonitoring))
$appInstance.AddProperty("$MPElement[Name='Microsoft.Dynamics.Retail.AX2012.R2.FP.Base.Class.SharePointWebApplication']/Url$", [string]($webAppUrl))

$discoveryData.AddInstance($appInstance)

$relationshipInstance = $discoveryData.CreateRelationshipInstance("$MPElement[Name='Microsoft.Dynamics.Retail.AX2012.R2.FP.Base.RelationShip.SharePointWebApplicationToServer']$")
$relationshipInstance.Source = $appInstance
$relationshipInstance.Target = $serverInstance
$discoveryData.AddInstance($relationshipInstance)

$logger.LogInfo($kSharePointECommerceDiscoveryECommerceWebAppDiscoveryDataAdded, ("Discovered Dynamics ECommerce web application. Name: {0}, Url: {1}, PublisherName: {2}, PublisherNameMonitoring: {3}" -f $webAppName, $webAppUrl, $webAppPublisherName, $webAppPublisherNameMonitoring))
}
}
else
{
$logger.LogInfo($kSharePointECommerceDiscoveryECommerceWebAppsNotFound, "Did not find any Dynamics ECommerce web applications deployed.")
}

# 4. Get timer jobs
$jobsKeyPath = $farmECommerceRegKeyPath + "TimerJobs"
if(Test-Path $jobsKeyPath)
{
$logger.LogInfo($kSharePointECommerceDiscoveryECommerceTimerJobsFound, "Found Dynamics ECommerce timer jobs deployed.")
Get-ChildItem $jobsKeyPath | % {
$jobName = $_.PSChildName
$jobProductCatalogUrl = $_.GetValue("Url")
$jobPublisherName = $_.GetValue("PublisherName")
$jobPublisherNameMonitoring = $_.GetValue("PublisherNameMonitoring")

$serverInstance = $discoveryData.CreateClassInstance("$MPElement[Name='Microsoft.Dynamics.Retail.AX2012.R2.FP.Base.Class.SharePointServer']$")
$serverInstance.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", [string]($computerName))
# ID must be unique, so the rule does not get cooked down
$uniqueId = ("{0} - {1}" -f [string]($computerName), $jobPublisherName)
$serverInstance.AddProperty("$MPElement[Name='Microsoft.Dynamics.Retail.AX2012.R2.FP.Base.Class.SharePointServer']/ID$", [string]($uniqueId))
$serverInstance.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", [string]$computerName)
$serverInstance.AddProperty("$MPElement[Name='Microsoft.Dynamics.Retail.AX2012.R2.FP.Base.Class.SharePointServer']/FarmID$", [string]($farmIdGuid.ToString()))
$serverInstance.AddProperty("$MPElement[Name='Microsoft.Dynamics.Retail.AX2012.R2.FP.Base.Class.SharePointServer']/PublisherName$", [string]($jobPublisherName))
$serverInstance.AddProperty("$MPElement[Name='Microsoft.Dynamics.Retail.AX2012.R2.FP.Base.Class.SharePointServer']/PublisherNameMonitoring$", [string]($jobPublisherNameMonitoring))
$discoveryData.AddInstance($serverInstance)

$jobInstance = $discoveryData.CreateClassInstance("$MPElement[Name='Microsoft.Dynamics.Retail.AX2012.R2.FP.Base.Class.SharePointTimerJob']$")

$jobInstance.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", [string]($jobName))
# ID must be unique in order for it to be aggreated. If we monitor 2 farms with the same objects, we would roll them up into one SCOM instance, hence we use farm id here as well
$uniqueId = ("{0} - {1}" -f $farmIdGuid.ToString(), $jobName)
$jobInstance.AddProperty("$MPElement[Name='Microsoft.Dynamics.Retail.AX2012.R2.FP.Base.Class.SharePointTimerJob']/ID$", [string]$uniqueId)
$jobInstance.AddProperty("$MPElement[Name='Microsoft.Dynamics.Retail.AX2012.R2.FP.Base.Class.SharePointTimerJob']/Name$", [string]($jobName))
$jobInstance.AddProperty("$MPElement[Name='Microsoft.Dynamics.Retail.AX2012.R2.FP.Base.Class.SharePointTimerJob']/FarmID$", [string]($farmIdGuid.ToString()))
$jobInstance.AddProperty("$MPElement[Name='Microsoft.Dynamics.Retail.AX2012.R2.FP.Base.Class.SharePointTimerJob']/PublisherName$", [string]($jobPublisherName))
$jobInstance.AddProperty("$MPElement[Name='Microsoft.Dynamics.Retail.AX2012.R2.FP.Base.Class.SharePointTimerJob']/PublisherNameMonitoring$", [string]($jobPublisherNameMonitoring))
$jobInstance.AddProperty("$MPElement[Name='Microsoft.Dynamics.Retail.AX2012.R2.FP.Base.Class.SharePointTimerJob']/Url$", [string]($jobProductCatalogUrl))

$discoveryData.AddInstance($appInstance)

$relationshipInstance = $discoveryData.CreateRelationshipInstance("$MPElement[Name='Microsoft.Dynamics.Retail.AX2012.R2.FP.Base.RelationShip.SharePointTimerJobToServer']$")
$relationshipInstance.Source = $jobInstance
$relationshipInstance.Target = $serverInstance
$discoveryData.AddInstance($relationshipInstance)

$logger.LogInfo($kSharePointECommerceDiscoveryECommerceTimerJobDiscoveryDataAdded, ("Discovered Dynamics ECommerce timer job. Name: {0}, ProductCatalogUrl: {1}, PublisherName: {2}, PublisherNameMonitoring: {3}" -f $jobName, $jobProductCatalogUrl, $jobPublisherName, $jobPublisherNameMonitoring))
}
}
else
{
$logger.LogInfo($kSharePointECommerceDiscoveryECommerceTimerJobsNotFound, "Did not find any Dynamics ECommerce timer jobs deployed.")
}
}
}

$logger.LogScriptExecutionSucceeded($kSharePointECommerceDiscoveryFinishedSuccessfully)
}
catch
{
$discoveryData = $null
$logger.LogScriptExecFailed($kSharePointECommerceDiscoveryFinishedWithError, ${global:error})
}
return $discoveryData
</Script></ScriptBody>
<Parameters>
<Parameter>
<Name>Target</Name>
<Value>$Target/Id$</Value>
</Parameter>
<Parameter>
<Name>Element</Name>
<Value>$MPElement$</Value>
</Parameter>
<Parameter>
<Name>ComputerName</Name>
<Value>$Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/PrincipalName$</Value>
</Parameter>
</Parameters>
<TimeoutSeconds>60</TimeoutSeconds>
</DataSource>
</Discovery>