Friday, June 6, 2014

SCOM Web Console and Internet Explorer 11

Yesterday decided to check that my SLA Dashboard works well in Web Console. All virtual machines in environment have Windows Server 2012 R2 onboard with Internet Explorer 11.
When I tried to connect I got this:


Isn't it funny? :) I've followed the link to MS TechNet and figured out that IE 11 is among supported browsers and Windows Server 2012 should not cause problems either.
I've tried connecting from other machines but the result was the same. Search in the internet didn't give me any idea how to solve this ridiculous issue.

I've went through IE settings and found this option in menu:



It allows adding web addresses which should be opened in Compatibility View. So I've added localhost, cause Web Console is on the same machine. On the other machine I had to add hostname of my Web Server.



... and right after that - voila!


Ah, this mystical Compatibility View!


 

Reusing SLA Dashboard in Your Management Pack

Hope

Operations Manager 2012 contains variety of dashboards and widgets which could be reused if the one doesn't want to mess up with widgets development.
So was I, monitoring distributed application which supposed to have Service Level Agreement.
I've picked SLA Dashboard.

It can be created with the wizard:


On this page you have to pick SLAs to be represented on the dashboard:

 
... and after completing all steps you get this nice layout:


I've exported Management Pack containing dashboard and after taking a look at Component code I've noticed the binding of some GUID to ServiceLevel property of the dashboard:
<Binding PropertyId="ServiceLevel">
  <ComplexValueCollection Type="mpschema://Microsoft.EnterpriseManagement.Configuration.ManagementPackConfigurationGroup[]">
    <ComplexValue Type="mpschema://Microsoft.EnterpriseManagement.Configuration.ManagementPackConfigurationGroup">
      <Binding PropertyId="Id">
        <SimpleValue Type="xsd://string" Value="50898fd4-9c74-1c1c-257f-d435d1ef13af" />
      </Binding>
    </ComplexValue>
  </ComplexValueCollection>
</Binding>

 This GUID is an identifier of Configuration Group containing Service Level Objectives. This group is actually Service Level Tracking which you create through wizard in Authoring:
<ConfigurationGroups>
  <ConfigurationGroup ID="KI.Test.SLA.ConfigurationGroup" Accessibility="Public" Target="KI.Test.DistributedApplication" />
</ConfigurationGroups>


Hope is Gone

But you can't hardcode GUID in you custom Management Pack cause this value will be different in every environment. In is case it is common to replace the hardcoded GUID with reference to a property of Management Pack object.
So did I:
<Binding PropertyId="ServiceLevel">
  <ComplexValueCollection Type="mpschema://Microsoft.EnterpriseManagement.Configuration.ManagementPackConfigurationGroup[]">
    <ComplexValue Type="mpschema://Microsoft.EnterpriseManagement.Configuration.ManagementPackConfigurationGroup">
      <Binding PropertyId="Id">
        <Reference>$MPReference/KI.Test.DA!KI.Test.SLA.ConfigurationGroup/Id$</Reference>
      </Binding>
    </ComplexValue>
  </ComplexValueCollection>
</Binding>

KI.Test.DA is an ID of my Management Pack, KI.Test.SLA.ConfigurationGroup is ID of SLA Configuration Group and Id is a property name which I want to be put into list of Service Levels represented on dashboard.
I didn't expect any problem here however...
I got this:



The reference was null or the property was null or empty... I've tried all possible properties and found out that I can get access to KI.Test.DA!KI.Test.SLA.ConfigurationGroup/DisplayName. But property ID was just empty. I've managed to get ID property of any other class like System.Group and others but not Configuration Group. It is obviously a bug.
Checked this on SP1 and R2.

Other Way

So it became obvious that I need to get GUID of Configuration Group some other way.
I definitely can do it using SDK. And I need to put it into some variable and reference it in this binding instead of KI.Test.DA!KI.Test.SLA.ConfigurationGroup/Id.

Basically solution is:
1. Create Data Provider which gets Configuration Group name as an input and returns GUID as string.
2. Create queries for WPF and Silverlight Consoles
3. Extend SLA Dashboard with Data Provider
4. Define new variable in SLA Dashboard
5. Map output to this variable
6. Reference this variable in Service Level list

Pretty serious workaround, ha?

So by the end I have three DLLs wrapped into Management Pack:
1) Data Provider (server-side)
2) Query for WPF (desktop console)
3) Query for Silverlight (web console)

... all this bustle because SCOM doesn't handle Configuration Groups properly.

The code samples below.

Retrieving Configuration Group Id from SDK

var critString = string.Format(
    CultureInfo.CurrentUICulture,
    "[Name] = '{0}'",
    configGroupName);

var crit = new ManagementPackConfigurationGroupCriteria(critString);
var configGroups = Connection.ServiceLevelAgreements.GetConfigurationGroups(crit);
var configGroupId = string.Empty;
foreach (var cg in configGroups)
{ configGroupId = cg.Id.ToString();
}

Extending SLA Dashboard with Data Provider

<Variable Id="ConfigGroupId" Type="xsd://string" />
<Base>
  <Binding PropertyId="ServiceLevel">
    <ComplexValueCollection Type="mpschema://Microsoft.EnterpriseManagement.Configuration.ManagementPackConfigurationGroup[]">
      <ComplexValue Type="mpschema://Microsoft.EnterpriseManagement.Configuration.ManagementPackConfigurationGroup">
        <Binding PropertyId="Id">
          <Reference>$Variable/ConfigGroupId$</Reference>
        </Binding>
      </ComplexValue>
    </ComplexValueCollection>
  </Binding>
  <Binding PropertyId="Objects">
    <Component TypeId="KI.Test.Queries.GetSlaConfigGroupIdQuery">
      <Binding PropertyId="ConfigurationGroupName">
        <SimpleValue Type="xsd://string" Value="KI.Test.SLT.ServiceHealth.ConfigurationGroup" />
      </Binding>
      <Binding PropertyId="ConfigurationGroupId">
        <Reference>$Variable/ConfigGroupId$</Reference>
      </Binding>
    </Component>
  </Binding>
</Base>
 


 
 
 
 

Friday, May 30, 2014

Why Health Doesn't Roll Up?

This problem appeared in SCOM 2012 RTM so I will talk about this version. The issue persists in all versions up to 2012 R2.

We need to understand how health rollup works to answer this question.
There is a workflow on SCOM Server which goes through the database and implements health roll up. It searches for the objects which need their health to be updated. It does not roll up health for all entities in  one run. There are thousands of them and such implementation would cause huge performance impact on server.
After working with numerous environments we've figured out that Health Rollup Workflow skips entities which are being changed very often. A typical scenario to reproduce rollup problem is to reinstall the same Management Pack many times.
When you develop a pack usually you make some changes and install the new version in your dev SCOM just to verify the improvements work. However sometimes you make changes which break the compatibility with previous versions of MP and you have to remove it before deployment of new one.
The trick is that SCOM doesn't remove discovered entities from the database right away after MP uninstallation. It just marks them as deleted. So when you install MP again you rediscover the same object with the same GUID and there is a huge chance that Health Rollup MP will skip it and you'll see the sad picture:

If you hit this issue, you could try to restart System Center Management service (Monitoring Service in 2012 R2) but in most cases it doesn't help.

You'll ask me what to do if you develop and just need to reinstall and you need health to be rolled up?
There is a hope! I've invented one trick how to get instant rollup guarantee.
I'll post it in one of the next posts, dear diary. Follow up.

Health Rollup to Singleton Auto-Populated Group

I was developing architecture where I discover couple hosted objects on agents which are contained in one System.Group. This group is a singleton and I used Microsoft.SystemCenter.GroupPopulator as a Data Source for discovery populating group with hosted objects.

<ClassTypes>
   <ClassType ID="SingletonGroup" Base="System!System.Group"

              Accessibility="Public" Abstract="false"
              Hosted="false" Singleton="true">
</ClassType>
 

...
<Discovery ID="SingletonGroupDiscovery" Enabled="true"
           Target="SingletonGroup"
           ConfirmDelivery="true" Remotable="true" Priority="Normal">
 <Category>Discovery</Category>
 <DiscoveryTypes>
   <DiscoveryClass TypeID="SingletonGroup" />
 </DiscoveryTypes>
 <DataSource ID="DiscoveryDataSource"
              TypeID="SC!Microsoft.SystemCenter.GroupPopulator">
   <RuleId>$MPElement$</RuleId>
   <GroupInstanceId>$Target/Id$</GroupInstanceId>
   <MembershipRules>
     <MembershipRule>
       <MonitoringClass>$MPElement[Name="HostedObject1"]$</MonitoringClass>
       <RelationshipClass>$MPElement[Name="Relationship.SingletonGroupContainsHostedObject1"]$</RelationshipClass>
     </MembershipRule>
     <MembershipRule>
       <MonitoringClass>$MPElement[Name="HostedObject2"]$</MonitoringClass>
       <RelationshipClass>$MPElement[Name="Relationship.SingletonGroupContainsHostedObject2"]$</RelationshipClass>
      </MembershipRule>
    </MembershipRules>
  </DataSource>
</Discovery> 
There was an option to create specific class instead of inheriting from System.Group, but then it would be necessary to implement discovery which creates relationships between group and hosted object, so I've picked a way with basic System.Group to keep things simple.
Implementation was easy and fast, then a quick verification that all objects and relations are being created, and done!
The next day tester informed me that he can't get health roll up from hosted objects to the group. That was confusing cause I didn't expect any troubles with that part - I had all necessary Dependency Monitors implemented.
So I had to ask myself a question: is it possible to roll up health from objects created and hosted by agent to a group which is auto-populated singleton.

Today I can answer this question positively. I've spend some time verifying this in dev environment. Health DOES ROLL UP.

But what was the problem in Test environment? Why health wasn't rolled up in a reasonable time?
That is a complicate problem, dear diary. I will answer these questions in a different post.
Right now I can say that it was not a problem of Management Pack code.

Thursday, May 29, 2014

Dear Diary...

Dear Diary,

I've been developing Management Packs for Microsoft System Center Operations Manager for almost three years. During this long time I've collected so much information about this system that I cannot keep it in my head. I really need to store it somewhere. So this is your destiny, dear friend - keep the knowledge safe and easy for search.