SCOM Subscription Issue – Notification Contains Indexed Placeholder Instead of Value in the AlertName

Yes, that’s a very long title, but it really describes the issue that was brought to the table last week. The original question was:

All of the notification emails for these alerts only contained {2} for the Subject and Alert Name.

That was something I haven’t heard before and I decided to do a quick research. As I had no access to the Exchange lab this time, I have created a sample management pack which triggers alerts with some random data. There were two monitors: one with the “static” name for the alert message and another with “dynamic” name. Here is the code for dynamic one:

<ManagementPackFragment SchemaVersion="2.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Monitoring>
    <Monitors>
      <UnitMonitor ID="OKSB.SubscriptionTest.Singleton.UM.RandomDataDynamic"
                   Accessibility="Public"
                   Enabled="true"
                   Target="OKSB.SubscriptionTest.Singleton"
                   ParentMonitorID="Health!System.Health.AvailabilityState"
                   Remotable="true"
                   TypeID="OKSB.SubscriptionTest.UMT.RandomData">
        <Category>Custom</Category>
        <AlertSettings AlertMessage="OKSB.SubscriptionTest.Singleton.UM.RandomDataDynamic.AlertMessage">
          <AlertOnState>Error</AlertOnState>
          <AutoResolve>true</AutoResolve>
          <AlertPriority>Normal</AlertPriority>
          <AlertSeverity>Error</AlertSeverity>
          <AlertParameters>
            <AlertParameter1>$Data/Context/Property[@Name='dt']$</AlertParameter1>
            <AlertParameter2>$Data/Context/Property[@Name='Random']$</AlertParameter2>
            <AlertParameter3>$Data/Context/Property[@Name='Title']$</AlertParameter3>
          </AlertParameters>
        </AlertSettings>
        <OperationalStates>
          <OperationalState ID="ErrorHealthState" MonitorTypeStateID="Unhealthy" HealthState="Error" />
          <OperationalState ID="SuccessHealthState" MonitorTypeStateID="Healthy" HealthState="Success" />
        </OperationalStates>
        <Configuration>
          <IntervalSeconds>180</IntervalSeconds>
          <TimeoutSeconds>600</TimeoutSeconds>
          <SyncTime/>
        </Configuration>

      </UnitMonitor>
    </Monitors>
  </Monitoring>
  <Presentation>
    <StringResources>
      <StringResource ID="OKSB.SubscriptionTest.Singleton.UM.RandomDataDynamic.AlertMessage"/>
    </StringResources>
  </Presentation>
  <LanguagePacks>
    <LanguagePack ID="ENU" IsDefault="true">
      <DisplayStrings>
        <DisplayString ElementID="OKSB.SubscriptionTest.Singleton.UM.RandomDataDynamic">
          <Name>
            OKSB Subscription Test: Random data unit monitor - dynamic title
          </Name>
        </DisplayString>
        <DisplayString ElementID="OKSB.SubscriptionTest.Singleton.UM.RandomDataDynamic.AlertMessage">
          <Name>{2} - dynamic title</Name>
          <Description>
            dt: {0}
            random: {1}
            title: {2}
          </Description>
        </DisplayString>
      </DisplayStrings>
    </LanguagePack>
  </LanguagePacks>
</ManagementPackFragment>

After that I have created a command channel and the subscription. I have passed this variable to the command:

"$Data[Default='Not Present']/Context/DataItem/AlertName$"

And the command allowed me to dump values of AlertName variables to the file. And here is what I’ve got:

SCOM Subscription Notification - Indexed Placeholder Instead of Value in the AlertName

The outcome of the research: The issue is confirmed – indexed placeholders are not processed properly by SCOM subscription engine. The issue is in the core product (SCOM itself), not in the management pack.

By the way, this issue affects not only Exchange Server 2013 Management Pack, but also some other MPs.

Frankly speaking, I can see two issues here:

  1. There is inconsistency in different components of System Center Operations ManagerĀ – consoles do process placeholders and subscription doesn’t.
  2. Some MP development teams should update their test plans to check subscription notifications.

Workarounds.

I do not like to implement workarounds just because they introduce unwanted complexity to systems, but in this case there is no other option – I don’t think that we’ll get the fix for the core product quickly.

Here are two options I can think of:

  1. For the Exchange 2013 MP: Setup a custom channel for exchange alerts and use $Data/Context/DataItem/ManagedEntityFullName$ variable instead of the AlertName variable. Exchange MP targets alerting workflows to either HealthSet or NTService, so using ManagedEntityFullName will give you the alert origin, alert description will give you the rest.
  2. Setup a custom command channel which will call PS script which will send email notification. You will need to pass AlertId to the script, code the script to get alert details via SCOM SDK and send an email. This workaround may be resource-intensive if you experience many alerts – test it before go-live. Here is the sample (sending emails is your homework if you decide to go for this option):
param($AlertId, $FromEmail, $ToEmail, $SmtpServer)

$sendLog = "C:\OKSB_Channel\sendlog.log"

# Replace this function with code to send email - you may use Send-MailMessage cmdlet for PS 3.0 and higher
function Send-SCOMAlert ($subject, $body)
{
   '###' >> $sendLog
   Get-Date -Format 'u' | Out-File -Append $sendLog
   "Via: {0}" -f $SmtpServer | Out-File -Append $sendLog
   "From: {0}" -f $FromEmail | Out-File -Append $sendLog
   "To: {0}" -f $ToEmail | Out-File -Append $sendLog
   "Subject: {0}" -f $subject | Out-File -Append $sendLog
   "Body:`r`n{0}" -f $body | Out-File -Append $sendLog
}

function Normalize-AlertDescription([string]$text)
{
    $newtext = $text.Replace(([char]10).ToString(),[char]13+[char]10)
    while($newtext.Contains("  ")){ $newtext=$newtext.Replace("  "," ") }
    return $newtext.Replace("`n ","`n")
}

$subjectTemplate = "Alert: {0}"
$bodyTemplate = "{0}"

Import-Module OperationsManager
New-SCOMManagementGroupConnection 

$alert = Get-SCOMAlert -Id $AlertId

Send-SCOMAlert ($subjectTemplate -f $alert.Name) (Normalize-AlertDescription ($bodyTemplate -f $alert.Description))

That’s it. If someone needs the sample MP to reproduce the issue, let me know in comments or via this page.

Leave a Comment