Creating Templates That Use Parameters

The template provider simplifies the process of specifying an updating consumer scenario by allowing one user to create a scenario with parameters for many users who need to specify the parameter values.

For more information about support and installation of this component on a specific operating system, see Operating System Availability of WMI Components.

The template provider is at the core of template implementation for scenarios. This provider is a Windows Management Instrumentation (WMI) instance provider implemented as an in-process COM server.

The functionality of the template provider is unrelated to the rest of the event correlator. Every time a template user creates an instance of a template class, the template provider creates a group of other instances that are specified by the template creator. The values of these instances are parameterized by the values of the template class instance, which are provided by the template user. When an instance of a template class is deleted, the template provider automatically deletes all of the instances it creates when the template instance is created.

Windows Server 2003: When you install WMI, the template providers are not loaded by default. To install the template providers, click Start, click Control Panel, double-click Add or Remove Programs, and then click Add/Remove Windows Components.

Implementing the template provider is a two-step process. First, create the class for the template parameters. The class is created by the template designer and must be designated as provided by the template provider.

The following example shows a valid template class.

[dynamic, provider("Microsoft WMI TemplateProvider")]
class CorrelationTemplate
{
  [key] string Scenario;
  string WatchClass;
  string WatchScopeExpr;
  string WatchProp;
  sint32 SomeValue;
};

Second, specify the low-level objects that must be created when a user creates a template instance. This is done by creating a series of instances of the MSFT_TemplateBuilder class, one for each instance that the template creator creates when a template user creates an instance of the template class.

The following example shows how to use the MSFT_TemplateBuilder class.

class MSFT_TemplateBuilder
{
  [key] string Name;
  [key] string Template;
  [notnull] object Target;
  string ControllingProperty;
  string NamespaceProperty;
  uint32 Order = 0;
};

If the Target instance to be created is not parameterized by the properties of the template class, then it is an embedded object.

The following example shows a Target instance that is not parameterized by the properties of the template class.

instance of MSFT_TemplateBuilder
{
  Name = "ExampleBuilder";
  Template = "CorrelationTemplate";
  Target = instance of __EventFilter
  {
    Query = {"SELECT * FROM __InstanceModificatinEvent "
             "WHERE TargetInstance ISA 'MyClass'"};
  };
  ControllingProperty = ;
  NamespaceProperty = ;
  Order = 1;
};

Typically, the values in the object to be created are parameters in the template. In the previous example, the template creator registers a filter for events of the type specified in the WatchClass property of the template.

The following property qualifiers for instance levels are available for parameterization of objects.

  • [template_arg(PropName)]
    Specifies that this property should receive the value of the property specified by PropName value of the template class.

    The following example assigns "ExampleBuilder" to SomeProperty if the value of Name were "ExampleBuilder".

    [template_arg(Name)] SomeProperty;
    
  • [template_val(SubstitutionString)]
    Specifies that this property should receive the value of SubstitutionString with all of the substitutions performed. SubstitutionString uses environment-variable-like syntax.

    The following example defines SomeProperty to receive "SELECT * FROM MyClass" if the property specified by WatchClass is MyClass. If the property specified by WatchClass is null, no substitution takes place, and SomeProperty would be "SELECT * FROM ".

    [template_val("SELECT * FROM %WatchClass%")] SomeProperty;
    

    More complex substitutions arise when dealing with substitutions involving SQL queries. To use the more complex string substitutions, place extension functions in the substitution string.

    The following extension functions are supported by the template provider.

    • %!ConditionalSubstitution("String",TemplatePropIdentifier)%
      Specifies that "String" is to be substituted only if the template instance property specified by TemplatePropIdentifier is not null. This is useful for templates that form SQL queries, which may or may not have a WHERE clause.

      The following example shows that "WHERE" will be substituted if WatchScopeExpr is not null.

      [template_val("SELECT * FROM %WatchClass% "
                    "%!ConditionalSubstitution("WHERE", WatchScopeExpr)% "
                    "%WatchScopeExpr%")] SomeProperty;
      

      It is not sufficient to require the WatchScopeExpr parameter to merely contain the "WHERE" keyword because the WHERE clause is also used in queries that have a WHERE clause. For these cases, it is necessary to prepend an AND to the WHERE clause. Use the ConditionalSubstitution extension function to solve this type of problem.

    • %!PrefixedWhereSubstitution(Identifier, QueryTemplatePropIdentifier)%
      Permits all of the property references of a valid WHERE clause of an SQL query to be prefixed with the value of "Identifier". The QueryTemplatePropIdentifier value must refer to a template parameter having a valid WHERE clause as its value. A valid WHERE clause is the substring of a valid SQL statement after the WHERE keyword. For example, suppose that the WatchScopeExpr of our sample CorrelationTemplate class had the value "A=1 and B=2 or C=3".

      The following example sets SomeProperty to the values defined in WatchScopeExpr.

      [template_val("SELECT * FROM InstanceModificationEvent "
                    "WHERE TargetInstance ISA '%WatchClass%' "
                    "%!ConditionalSubstitution("AND", WatchScopeExpr)% "
                    "%!PrefixedWhereSubstitution(TargetInstance,
                        WatchScopeExpr)%"] SomeProperty;
      

      The following example shows the values that are used to set SomeProperty.

      SELECT * FROM __InstanceModificationEvent
      WHERE TargetInstance ISA 'MyClass' 
      AND TargetInstance.A=1 
      AND TargetInstance.B=2 
      OR TargetInstance.C=3
      
  • [template_ref(ReferenceString)]
    Specifies that this property contains a reference to the object instance created by the template builder. The ReferenceString property must be the reference of a template builder. When the template builder creates an object instance, the reference of that object is stored in the property. The user must have some control over the order in which object instances are created by the template builder. This order is prescribed by the Order property of the template builder.

    The following example shows how to use the template_ref qualifier.

    [template_ref("TemplateBuilder.Name=\"MyBuilder\", Template=\"ExampleTemplate\"")] RefProp;
    

    The following example shows that aliases can be used in the place of a reference when using the MOF compiler.

    [template_ref($MYREF)] RefProp;
    

    Note   Nothing prevents the embedded template object of the template builder from being another template. This permits templates being nested inside other templates.

Associations can be created between a template instance and the instances that the template builder objects create on instance creation. These associations cannot be rule-based, because they rely on creation information kept by the template provider.

The following example shows how the association is defined.

MSFT_TemplateAssociation
{
  [key] MSFT_TemplateBase ref Template;
  [key] object ref Target;
};

The template provider always impersonates the client of its methods, thereby ensuring that actions performed by the template provider, such as instance creations, are done by using the identity of the caller.

When creating template instances, the template provider returns error information in a COM error object that implements IWbemClassObject.

The following example shows how the COM error object is defined.

class TemplateErrorStatus : __ExtendedStatus
{
  string ErrorStr;
  string Property;
  object Target;
  MSFT_TemplateBuilder Builder;
  object ExtendedStatus;
};

Caution  Any user with partial write privileges in a namespace can modify a template definition. However, the user would not have the permissions needed to instantiate the template. If a template is instantiated by an administrator, the template creates objects by using the administrator permissions.

The namespace object passed to the template provider at initialization is kept by the template provider. If you change the security for the namespace, the template provider continues to function under the old security settings until you reload the template provider.