Management Pack Authoring in SCOM SDK – Quick Start Guide


Well, it has been quite a holiday! My wife delivered our son, Jamison Jakub, on December 26th at 8:14 AM. Mom and baby are doing great. I’ve posted some photos on our families personal site: www.oleksyfamily.com. I am more or less back at work for now and will be taking my paternity leave later, most likely after we ship SCOM 2007.

I wanted to talk a little about management pack authoring and editing in the SDK. This is the largest part of the SDK that I did not write, so I am not an expert at the internal workings of a lot of it, but I do know how it works.

First, there is a rather large object hierarchy when it comes to management pack related objects. At the most derived level, you will almost always find a Monitoring* object derived from a ManagementPack* object (e.g. MonitoringRule and ManagementPackRule). Monitoring* objects are returned by the online, connected SDK from the database. These objects are not “newable” and contain slightly more context, and sometimes more functionality, then their respective base class. (For instance they always have a pointer to ManagementGroup, which ManagementPack* object do not). Whenever you want to create a new management pack object, you have to use the ManagementPack* version of it to create it.

The context of a management pack object is always a management pack. When you create an object, you need to specify which management pack it goes into. This is the management pack that the ultimate commit call (AcceptChanges()) will need to be made.

If you want to change an existing object, simply change whatever you want about it (i.e. any settable properties) and then set its Status property to PendingUpdate. Once you do this, internally it gets placed into a pending changes collection for that management pack. But which instance you might ask? If you are working in connected SDK and you retrieve a management pack object from the database that object belongs to a particular management pack. Internally, this management pack is cached (unless you are running on CacheMode.None in which you should not be doing management pack authoring) and we always maintain the same instance of that management pack. No matter how many times you retrieve that object, that management pack instance will be the same. In fact no matter how you retrieve that management pack (with the ONE caveat that if you do criteria based searching for a management pack, the instance will actually be different as it doesn’t use the cache to perform the query) it will be the same instance.

This poses an interesting problem in that if multiple users in the same application try to update the same management pack, they will be writing into the same management pack at the same time. To alleviate this problem, the ManagementPack class exposes a LockObject property that will lock the management pack for editing. This lock should be taken prior to updating the management pack and released after committing the changes.

In order to commit changes, simply retrieve the management pack you are changing (either by calling GetManagementPack() on the object(s) you are changing, or some other independent SDK method that is not criteria based) and call AcceptChanges(). Once this method returns, the changes are committed.

I am sure users will have questions in this area, but it is such a large topic to cover, I just wanted to put together a small quick start guide to get everyone started. As always, please ask any questions you might have or if you want an expanded post on anything in particular regarding this area.


Comments (88)

  1. austinliu says:

    How can I add a normal parameter for the task in MP.

    If the parameter name is P1, the type is string and the default value is value1.

    Please help me on that.

    Thanks in advance.

  2. austinliu says:

    It is a script based task.

  3. If you are using the Microsoft.Windows.ScriptWriteAction the arguments to the script are passed in using a single Arguments field:

    <Task ID="YourTask" Target="YourTarget" Enabled="true" Accessibility="Public">

               <Category>Maintenance</Category>

               <WriteAction TypeID="Windows!Microsoft.Windows.ScriptWriteAction" ID="Script">

                   <ScriptName>YourScriptName.vbs</ScriptName>

                   <Arguments>value1</Arguments>

                   <ScriptBody>

                       <![CDATA[Your script]]>

                   </ScriptBody>

                   <TimeoutSeconds>120</TimeoutSeconds>

               </WriteAction>

           </Task>

  4. austinliu says:

    ya, I know.

    But where can I put the parameter name P1? I want to let user change that from the GUI of SCOM. You know when user run the task, the parameter name can not be found(always as Arguments). User will not know what’s the meaning of that parameter.

    thanks again.

  5. austinliu says:

    I mean change the default value of the parameter. I know user can change that by click the overide button. But he dont know the (Name)meaning of the parameter, that will be a problem

  6. Here is another example I pulled from one of our MPs. You want to look at the overrideable parameter in the definition. This will map up to your parameter. Also, you can add a display name using display strings to your overrideable parameter to be a bit more descriptive.

    <WriteActionModuleType ID="Microsoft.SystemCenter.EnableACSAction" Accessibility="Internal" Batching="false">

                   <Configuration>

                       <xsd:element name="CollectorServer" type="xsd:string"/>

                   </Configuration>

                   <OverrideableParameters>

                       <OverrideableParameter ID="CollectorServer" Selector="$Config/CollectorServer$" ParameterType="string"/>

                   </OverrideableParameters>

                   <ModuleImplementation Isolation="Any">

                       <Composite>

                           <MemberModules>

                               <WriteAction ID="EnableACS" TypeID="System!System.CommandExecuter">

                                   <ApplicationName>%windir%system32cscript.exe</ApplicationName>

                                   <WorkingDirectory/>

                                   <CommandLine>//NoLogo $File/EnableACSAction.vbs$ "$Config/CollectorServer$" "$Target/ManagementGroup/Name$"</CommandLine>

                                   <TimeoutSeconds>30</TimeoutSeconds>

                                   <RequireOutput>true</RequireOutput>

                                   <Files>

                                       <File>

                                           <Name>EnableACSAction.vbs</Name>

                                           <Contents><![CDATA[]]></Contents>

                                       </File>

                                   </Files>

                               </WriteAction>

                           </MemberModules>

                           <Composition>

                               <Node ID="EnableACS"/>

                           </Composition>

                       </Composite>

                   </ModuleImplementation>

                   <InputType>System!System.BaseData</InputType>

               </WriteActionModuleType>

  7. austinliu says:

    Sorry, I dont know where can I to put the <Configuration>

                      <xsd:element name="CollectorServer" type="xsd:string"/>

                  </Configuration>

                  <OverrideableParameters>

                      <OverrideableParameter ID="CollectorServer" Selector="$Config/CollectorServer$" ParameterType="string"/>

                  </OverrideableParameters>

    into a task definition like <Task ID="YourTask" Target="YourTarget" Enabled="true" Accessibility="Public">

              <Category>Maintenance</Category>

              <WriteAction TypeID="Windows!Microsoft.Windows.ScriptWriteAction" ID="Script">

                  <ScriptName>YourScriptName.vbs</ScriptName>

                  <Arguments>value1</Arguments>

                  <ScriptBody>

                      <![CDATA[Your script]]>

                  </ScriptBody>

                  <TimeoutSeconds>120</TimeoutSeconds>

              </WriteAction>

          </Task>

    I tried several times. All failed.

    Any artical I can read for that?

    Please help me out. Thanks

  8. I am not sure I understand the question. What are you trying that is failing?

  9. austinliu says:

    I tried to put the parameter definition into the task like

    <Task ID="YourTask" Target="YourTarget" Enabled="true" ccessibility="Public">

              <Category>Maintenance</Category>

    <Configuration>

                     <xsd:element name="CollectorServer" type="xsd:string"/>

                  </Configuration>

                  <OverrideableParameters>

                     <OverrideableParameter ID="CollectorServer" Selector="$Config/CollectorServer$" ParameterType="string"/>

           </OverrideableParameters>

              <WriteAction TypeID="Windows!Microsoft.Windows.ScriptWriteAction" ID="Script">

                  <ScriptName>YourScriptName.vbs</ScriptName>

                  <Arguments>value1, </Arguments>

                  <ScriptBody>

                      <![CDATA[Your script]]>

                  </ScriptBody>

                  <TimeoutSeconds>120</TimeoutSeconds>

              </WriteAction>

          </Task>

    It can not pass the xsd verification. I also tried to move the configuration to an other place. It doesnot work also.

  10. Can you provide me with the error you are getting?

  11. austinliu says:

    If I put the configuration like that, I will get a error message when I try to import the MP

    Invalid Management Pack : C:Documents and SettingsAdministratorDesktoptest.xml .: XSD verification failed for management pack. [Line: 572, Position: 6]

    The element ‘Task’ has invalid child element ‘Configuration’. List of possible elements expected: ‘ProbeAction, WriteAction’.

    I also tried to put the <Configuration> under writeaction. Also failed.

  12. Ah, I see the problem. If you notice in my original post, this is part of a WriteActionModuleType definition, not a task definition. You need to define it in the module type, then use that module type in a task. A task itself has no configuration. Sorry for not seeing this earlier.

  13. austinliu says:

    I tried to put <WriteActionModuleType ID =….>

    <WriteActionModuleType> into the management pack. Even I can not find a place for them. I searched that from Demo MP, sys MP, MP Authoring Guide, SDK. Could you please point out where can I get a reference for such task with new WriteActionModuleType? Thanks for your help

  14. Please take a look at the management pack that is attached to this post:

    http://blogs.msdn.com/jakuboleksy/archive/2006/09/27/Sample-Alert-and-State-Change-Insertion.aspx

    It will show you where in the management pack they go.

  15. austinliu says:

    OK, I got it. Thanks for your time.

  16. austinliu says:

    BTW, do you know how to make a task parameter in secure mode like password.

  17. Yes. There are several steps involved.

    First, you have to define a secure reference in a management pack. Secure references go into the TypeDefinitions section of the management pack:

    <SecureReferences>

               <SecureReference ID="TestAccount"  Context="System!System.Entity"/>

           </SecureReferences>

    This will show up in the UI as a Run As Profile. Next, you will need to setup a Run As Account in the UI, which will securely store your password.

    Now, go to your Run As Profile and specify on the second tab page what Run as Account you want to use, for whichever computer(s) you want. In your

    task configuration now, you will need to specify your Run As Account $RunAs[Name=”MyMP.TestAccount”]/Password$ which will be replaced securely by

    the Run As Account data you setup.

    If you are doing this for a script, the configuration already allows for secure input:

    <SecureInput>

                   $RunAs[Name="MyMP.TestAccount"]/Password$

    </SecureInput>

    Which you can then retrieve in your script via:

    Password = WScript.StdIn.ReadLine()

  18. austinliu says:

    Hi,

    I got another question. If I already inserted one custommonitoringobject, then I can get the monitorning object in an other program. How can I change the properties of the monitoring object by SDK?

  19. You need to use the same discovery data api you used to insert the CustomMonitoringObject to begin with. Just re-insert the object with the new values, and it will be updated accordingly.

  20. austinliu says:

    Great, it works. Thank you so much.

    One problem more. As I know, CustomMonitoringEventMessage is a part of CustomMonitoringEvent. I set a string "…." as the message of one event. When I open the event view, I can find the event. But I can not get the event message. Is it a bug of SCOM or I am looking into a wrong place ?

  21. This was a bug in RC2. The latest bits have this issue resolved.

  22. austinliu says:

    Many thanks for the help.

  23. austinliu says:

    Hi, I tried the secure input in RC2. It gives me the error message like below.

    XSD verification failed for management pack. [Line: 1629, Position: 3]

    The element ‘TypeDefinitions’ has invalid child element ‘SecureReferences’.

    I searched for xsd file for SCOM. But can not find that(ManagementPackSchema.xsd).

    Any comments?

  24. Check out http://www.authormps.com/.

    It should definitely be in the type definitions section. Can you take a look at the site and see if you put it in the same order as the schema? If you did, can you attach the MP? I am pretty sure the schema did not change for secure references since RC2.

  25. austinliu says:

    sorry, I dont know how to attach a file. I tried put the SecureReferences into Microsoft.Demo.Monitors.xml like

    <TypeDefinitions>

    <EntityTypes>

    <ClassTypes>

    <ClassType ID="Microsoft.Demo.Monitors.AppX" Abstract="false" Accessibility="Public" Hosted="true" Base="Windows!Microsoft.Windows.LocalApplication">

    <!– This class represents some Windows Application–>

    <!– There can only be one instance on a given computer so no key is required–>

    <Property ID="Version" Type="string"/>

    <Property ID="Path" Type="string"/>

    </ClassType>

    <ClassType ID="Microsoft.Demo.Monitors.AppXComponent" Abstract="false" Accessibility="Public" Hosted="true" Base="Windows!Microsoft.Windows.ApplicationComponent">

    <!– This class represents a component of a Windows Application–>

    <!– There can be multiple instances for a given AppX so a key has been specified–>

    <Property ID="ID" Type="string" Key="true"/>

    <Property ID="FileName" Type="string"/>

    </ClassType>

    </ClassTypes>

    <RelationshipTypes>

    <RelationshipType ID="Microsoft.Demo.Monitors.AppXHostsAppXComponent" Accessibility="Public" Base="System!System.Hosting">

    <!– A hosting relationship to state that the AppXComponent is part of the AppX and that it’s identity and life is dependend upon AppX–>

    <!– Note that you do not have to define that Computer Hosts AppX because Windows Computer Hosts Windows Application and AppX is a Windows Application–>

    <Source>Microsoft.Demo.Monitors.AppX</Source>

    <Target>Microsoft.Demo.Monitors.AppXComponent</Target>

    </RelationshipType>

    </RelationshipTypes>

    </EntityTypes>

    <ModuleTypes>

    <DataSourceModuleType ID="Microsoft.Demo.Monitors.AppX.DiscoveryProvider" Accessibility="Internal">

    <!– This datasource defines a script that will be used to discover AppX and AppX Component–>

    <!– See the Microsoft.Demo.Scripting MP for more details on this–>

    <Configuration>

    <xsd:element name="IntervalSeconds" type="xsd:integer"/>

    <xsd:element name="Computer" type="xsd:string"/>

    </Configuration>

    <OverrideableParameters>

    <OverrideableParameter ID="IntervalSeconds" ParameterType="int" Selector="$Config/IntervalSeconds$"/>

    </OverrideableParameters>

    <ModuleImplementation>

    <Composite>

    <MemberModules>

    <DataSource ID="DS" TypeID="Windows!Microsoft.Windows.TimedScript.DiscoveryProvider">

    <IntervalSeconds>$Config/IntervalSeconds$</IntervalSeconds>

    <SyncTime/>

    <ScriptName>DiscoveryAppX.vbs</ScriptName>

    <Arguments>$MPElement$ $Target/Id$ $Config/Computer$</Arguments>

    <ScriptBody><![CDATA[

    Option Explicit

    Dim oArgs

    Set oArgs = WScript.Arguments

    if oArgs.Count < 3 Then

      Wscript.Quit -1

    End If

    Dim SourceID, ManagedEntityId, TargetComputer

    SourceId = oArgs(0)

    ManagedEntityId = oArgs(1)

    TargetComputer = oArgs(2)

    Dim oFso

    Set oFso = CreateObject("Scripting.FileSystemObject")

    Dim oAPI, oDiscoveryData, oInst

    Set oAPI = CreateObject("MOM.ScriptAPI")

    set oDiscoveryData = oAPI.CreateDiscoveryData(0, SourceId, ManagedEntityId)

    If (oFso.FolderExists("C:AppX")) Then

    ‘ Create the Application instance

    set oInst = oDiscoveryData.CreateClassInstance("$MPElement[Name=’Microsoft.Demo.Monitors.AppX’]$")

    call oInst.AddProperty("$MPElement[Name=’Windows!Microsoft.Windows.Computer’]/PrincipalName$", TargetComputer)

    call oInst.AddProperty("$MPElement[Name=’Microsoft.Demo.Monitors.AppX’]/Version$", "2.0")

    call oInst.AddProperty("$MPElement[Name=’Microsoft.Demo.Monitors.AppX’]/Path$", "C:AppX")

    call oInst.AddProperty("$MPElement[Name=’System!System.Entity’]/DisplayName$", "Application X")

    call oDiscoveryData.AddInstance(oInst)

    ‘ Discovery Application Components

    Dim oFolder, oFile

    Set oFolder = oFso.GetFolder("C:AppX")

    For each oFile in oFolder.Files

    set oInst = oDiscoveryData.CreateClassInstance("$MPElement[Name=’Microsoft.Demo.Monitors.AppXComponent’]$")

    call oInst.AddProperty("$MPElement[Name=’Windows!Microsoft.Windows.Computer’]/PrincipalName$", TargetComputer)

    call oInst.AddProperty("$MPElement[Name=’Microsoft.Demo.Monitors.AppXComponent’]/ID$", StripExtension(oFile.Name))

    call oInst.AddProperty("$MPElement[Name=’Microsoft.Demo.Monitors.AppXComponent’]/FileName$", oFile.Name)

    call oInst.AddProperty("$MPElement[Name=’System!System.Entity’]/DisplayName$", StripExtension(oFile.Name))

    call oDiscoveryData.AddInstance(oInst)

    Next

    End If

    ‘ Submit the data

    Call oAPI.Return(oDiscoveryData)

    Function StripExtension (sFile)

    StripExtension = Left(sFile, Len(sFile) -4)

    End Function

    ]]></ScriptBody>

    <TimeoutSeconds>20</TimeoutSeconds>

    </DataSource>

    </MemberModules>

    <Composition>

    <Node ID="DS"/>

    </Composition>

    </Composite>

    </ModuleImplementation>

    <OutputType>System!System.Discovery.Data</OutputType>

    </DataSourceModuleType>

    </ModuleTypes>

       <SecureReferences>

         <SecureReference ID="TestAccount"  Context="System!System.Entity"/>

       </SecureReferences>

     </TypeDefinitions>

    It gives me error message as "XSD verification failed for management pack. [Line: 149, Position: 6]

    The element ‘TypeDefinitions’ has invalid child element ‘SecureReferences’. List of possible elements expected: ‘MonitorTypes’.".

  26. Please take a look here:

    http://www.authormps.com/dnn/MPSchema/TypeDefinitions/tabid/61/Default.aspx

    Secure references need to be placed before module types.

  27. austinliu says:

    OK, got it.

    You mentioned before that"Now, go to your Run As Profile and specify on the second tab page what Run as Account you want to use, for whichever computer(s) you want. In your task configuration now, you will need to specify your Run As Account $RunAs[Name=”MyMP.TestAccount”]/Password$ which will be replaced securely by the Run As Account data you setup.If you are doing this for a script, the configuration already allows for secure input:

    <SecureInput>

    $RunAs[Name="MyMP.TestAccount"]/Password$

    </SecureInput>

    Which you can then retrieve in your script via:

    Password = WScript.StdIn.ReadLine()

    "

    I want use the account in a script. But the script is not for a computer. So I cannot associate the run As profile with an computer in the second tap, then the run as profile will not has a run as count value. How can I do for that?

  28. When you are creating the run as account in the UI, you don’t need to create it was a windows account. There is a drop down that allows you to select different account types. Once you create this run as account, you can use it as described.

  29. austinliu says:

    yes, sure. Acturally I created a Basic Authentication. But TestAccount is a run as profile. I need to associate the TestAccount with the Basic Authentication. So on the second tap page, I need to add the Basic Authentication with an computer. I thought it can not work. But I tried just now, I can get the password in script. Thanks

    Another question, the run as account is a pair of accountname and Password. Can I get the accountname in the script?

  30. Yep. $RunAs[Name="MyMP.TestAccount"]/UserName$. But you will have to pass it in as config, you can’t reference it directly from the script.

  31. austinliu says:

    got it. Thanks

  32. austinliu says:

    As I know, MOM has the state property for the class. So we can customer the state easily.

    How can we define our own state property in SCOM? Not want to use available, Configuration.etc

  33. flystone says:

    hi,i’m a newer to SCOM

    i’m working for making a MP with diagram of custom icons,but i found nothing i can do by UI since last week.

    can i do it by sdk?

    thanks much

  34. In reply to austinliu – I assume you mean creating a new root monitor to roll up your other monitors to. You can do this by creating an aggregate monitor in a management pack and having the parent of that monitor be System.Health.EntityState, which is defined in the System.Health.Library. I don’t think the OpsMgr UI supports this, but the authoring console will.

    Please let me know if this is what you were looking for and if you need more information as to how to implement it.

  35. In reply to flystone – you can’t do this in the UI. The way to do this is the put images in a management pack and create image references between those images and the classes that you want the UI to show these images for. I don’t have an example handy, but if you look at the System.Image.Library (just export it) then you will see an example that we ship that uses this. Please let me know if you need more help with this. Again, the authoring console will let you do this and I believe the beta of this is available. Let me know if this helps or if you need other help.

  36. flystone says:

    thank u very much for your reply so quickly:) it seems that "authoring console" is a single tool for make mps.

    but where can i find it?

    thanks

  37. austinliu says:

    I defined a class "Test_Class" based on "windows user application". I also defined an aggregate monitor like

    – <AggregateMonitor ID="Communication" Accessibility="Public" Enabled="true" Target="Test_Class" ParentMonitorID="Health!System.Health.EntityState" Remotable="true" Priority="Normal">

     <Category>PerformanceCollection</Category>

     <Algorithm>WorstOf</Algorithm>

     </AggregateMonitor>

    But I still got the four monitors like usual. (Availablity, Configuration, Performace, Security).

    Anything I missed?

    Thanks

  38. austinliu says:

    To flystone. I remembered I downloaded the "authoring console" from a package on connect.microsoft.com, but I can not find the link anymore.

  39. austinliu says:

    To JakubOleksy:

    After I instered an object of "Test_Class", I saw the "Communication" monitor in the Healthy explorer window. But still can not find that in the detail view, when I click the test object in the computer state view. Is it a bug of RC2 or I missed something?

  40. To flystone: I just checked on it and it looks like the authoring console was a limited release available on the connect site, to I believe only TAP customers, although I am not sure if it was limited to that. We are planning on releasing a beta of it in a few months, but it is not widely available yet. Are you on the TAP program or otherwise have any Microsoft contacts regarding SCOM. Please send me an email directly and let me know.

    To austinliu: This is actually by design. The state view shows those monitors by default. If you want to change those monitors you will have to author your own state detail view and target to your type. It will automatically be picked up when you have a state view for your type. Here is an example from the windows server management pack:

    <View ID="Microsoft.Windows.Server.2000.OperatingSystem.State.DetailsView" Target="Microsoft.Windows.Server.2000.OperatingSystem" TypeID="SC!Microsoft.SystemCenter.StateDetailDefinitionViewType" Visible="true" Accessibility="Internal">

           <Category>Operations</Category>

           <Monitors>

             <Monitor>$MPElement[Name="SystemHealth!System.Health.AvailabilityState"]$</Monitor>

             <Monitor>$MPElement[Name="SystemHealth!System.Health.ConfigurationState"]$</Monitor>

             <Monitor>$MPElement[Name="SystemHealth!System.Health.PerformanceState"]$</Monitor>

             <Monitor>$MPElement[Name="Microsoft.Windows.Server.2000.OperatingSystem.CoreServicesRollup"]$</Monitor>

             <Monitor>$MPElement[Name="Microsoft.Windows.Server.2000.OperatingSystem.MemoryAvailableMBytes"]$</Monitor>

             <Monitor>$MPElement[Name="Microsoft.Windows.Server.2000.OperatingSystem.TotalCPUUtilization"]$</Monitor>

           </Monitors>

         </View>

  41. austinliu says:

    ok, i c. Thanks for you input

  42. flystone says:

    hi,thanks

    i’ve added my icon by hand according to your reference:)

  43. austinliu says:

    Hi,

    If I want to use WMI event to trigger SCOM event on one object, how can I implement that?

    Any example can be refered?

    Thanks

  44. austinliu says:

    As I know, if we have one Unitmonitor on the object, the state of the object will be set to healthy. Can I change the default value to "notmonitored" as default?

    If I can set the default state value to "notmonitored". How can I set the value to healthy when I insert the object?  

    Too many questions. Thanks for your help

  45. Regarding the WMI event question, a good place to start is the UI. If you go to the authoring space and create a new rule or monitor, there are built-in templates the use the various WMI data sources. You can create themt this way and if you are interested in what the generated management pack looks like, simply export the management pack you put the monitor/rule into.

    Regarding the "Not Monitored" question, you cannot change what a monitor initializes to. "Not Monitored" means that the monitor is not yet running for that particular object.

  46. austinliu says:

    Yes, I did created a rule using the type"Collection Rules/Event Based/WMIEvent". I specified the query language and WMI namespace in the "DataSource". But the "WriteActions" only has "WriteToDB" and "WritetoDW" as the default. Then I changed the response action to run a customer script. I just want to generate the SCOM Event in the script. Am I doing right?

    How can I use the WMI query result in the script?

  47. When you say you want to generate the SCOM event in the script, what do you mean? If you just create a WMI Event collection rule as you have done, it will collect the events for you.

    In order to access the WMI result from the script, assuming the previous module in your rule/monitor is the WMI module, you can use the $Data/Property@Name="<Your Property Name>"$ syntax. The $Data/*$ syntax is really just an xpath expression into the incoming data item.

    Eventually the MP authoring site I have linked should cover the more advanced topic of data item querying from within modules and scripts.

  48. One point of clarification. The $Data/*$ syntax must be used to pass in configuration into your script. You cannot use the syntax directly from within your script.

  49. austinliu says:

    ok, I already registered on the site.

    As I know, we can create events by using ScriptContext.CreateEvent in MOM2005. Can we do that in SCOM2007? I just found three methods for MOMDiscoveryData, nothing for event.

    If can not, do we have any work around?

  50. Are you just trying to collect the event? If so, you can just create a collection rule. Otherwise, can you elaborate on what you are trying to accomplish.

    We no longer support the CreateEvent API from the script context.

  51. austinliu says:

    yes, I want to generate the event according to the WMI event query result. Different event number for different WMI class(some other changes also). Then the event number will triger the changing of object state by monitors.

    I know maybe we can use the monitor with WMI event directly. But we want the customer event also.

  52. Ok, let me try to clarify some things.

    First, you don’t need an event to trigger a state change. In fact, what you are asking to do won’t work at all in the fashion that you are proposing. What you really need here is two seperate workflows to do the two different things you want to do.

    First, to collect the event you need a rule. If you don’t like the way we do the mapping via the template provided in the UI, you will need to write your own rule manually. This rule should use the Microsoft.Windows.WmiEventProvider datasource and then the System.Event.GenericDataMapper to map the incoming WMI data item into an event, then use the database write action as the rule the template produces does. This will create the event as you want it in the DB. However, changing the event id based on the class will not work unless you also include an event filter before the mapper to filter on the class, then hardcode the event number.

    For state, you need to create a seperate monitor that uses the WmiEventProvider. The UI has templates to do this and I would recommend using those.

  53. austinliu says:

    Thank you for your advise.

    I still have the questions on the expression. If I use the expression, can I define 2 or more events with different event number in one rule?

    Let me give a example. We have two properies in the WMI query result, named P1, P2. P1 has two values, named value11, value12. P2 has value21, value22. Now we want to define the event number as below.

    map value11 value21 to Enum1

    map value11 value22 to Enum2

    map value12 value21 to Enum3

    map value12 value22 to Enum4

    Then we need 4 rules on that, am I correct?

    Can I wrap a COM as an interface for my script and SDK. Then I can use swich-case in that.  Does Microsoft recommend this kind of model?

  54. Yes, you can just use multiple rules for this. You can also do a single rule, but this would require defining your own composite module type and would be more complicated then just defining multiple rules. With our infrastructure, the performance would be about the same for both solutions.

  55. austinliu says:

    sorry, what do you mean the both solutions? Single rule and mutiple rules or rule and SDK method?

  56. I meant using a single rule, for which you write a composite module type and defining multiple rules.

  57. austinliu says:

    So how about the COM interface I mentioned before? I think SCOM SDK provides a couple of ways.  I want to make a COM object as an interface for our script and SCOM SDK.

    Any disadvantage for that?

  58. So you want to write a script that will call into a COM interface that will use the SDK to insert these events? You could do that if you wanted, although now your rule will have to run only on agents that have SDK access and your component will have to run with proper SDK permissions.

    Seems this would be a more complicated route, but it should work as well.

  59. austinliu says:

    Hi, can you tell me how to know if the agents have SDK access or not?

    I dont want to use the SDK also. But it is hard for me to find a example for my case.

    let me try to clarify that.

    There are two ways you suggested.

    1. Defining multiple rules

    Actually I need to define a DataSourceModule(named DSEx) like Microsoft.Windows.WmiProvider.FilteredEventProvider. I will put the event number as a parameter into configuration also, then I will define multiple rules using DSEx.

    But I dont know how to use the WMI query result in the expression? and there are hundreds of switch-cases. So that will not be a good implementation.

    2. Write a composite module type.

    I have no idea about that, can you give me a example?

  60. Could you email me via the email link on the right. Let’s take this offline and try to get it resolved. When you do email me, could you provide a more general overview of what your end goal is? What are you trying to accomplish via the WMI mechanism we have been discussing.

    With that information and if I can’t help, I’ll put you in touch with some coworkers of mine responsible for the management pack infrastructure that will best be able to guide you down the right path.

  61. agrawal_r_k says:

    I have a use case wherein i need to disable discovery of a specific computer for 2-3 management packs.

    Can i override a discovery using SDK ? if yes then how can i override.

    I am also not able create object of DiscoveryData class. The sdk documentation i have states that there is a DiscoveryData class in Microsoft.EnterpriseManagement.Administration namespace. But when i try to use this it gives me compile time error. I am using SDK shipped with RTM.

  62. Yes, you can override a discovery by creating a new ManagementPackDiscoveryPropertyOverride object. You would just create an Enabled property override to disable whichever discoveries you want. When you new the object, it will require a management pack which is the management pack you want the override to go into. Once created, you commit by calling AcceptChanges() on the ManagementPack object.

    Regarding the DiscoveryData class, it is now called IncrementalMonitoringDiscoveryData or SnapshotMonitoringDiscoveryData and is found in the Microsoft.EnterpriseManagement.ConnectorFramework namespace. Please reference this post:

    http://blogs.msdn.com/jakuboleksy/archive/2006/11/07/inserting-operational-data-2.aspx

  63. nicolasmohamed@gmail.com says:

    Hi! I am currently developing an MP and got stuck with a monitor evaluation

    The scenario is simple, I have 4 databases (SQL 2005) and I want to change the availability of any of them from my script monitor.

    In the script, I populate the PropertyBag with these values:

    MASTER ONLINE

    MODEL ONLINE

    etc..

    The I want the health to depend on these values for each instance of my DBClass

    I put the following in the XPathQuery

    Property[@Name=$Target/Property[Type="DB.Class"]/DBName$]

    Does not equal ONLINE

    but it doesn’t seem to work.. all I see is the four databases ONLINE when I know for sure that one of them is OFFLINE.

    I appreciate your help

    Thanks

    Nicolas

  64. nicolasmohamed@gmail.com says:

    IT WORKED USING

    Property[@Name=’$Target/Property[Type="DB.Class"]/DBName$’]

    NOTICE THE SINGLE QUOTES–

    THANKS

    NICOLAS

    nicolas@lagash.com

  65. tonyh413 says:

    Is it possible to manufacturer static instances of classes using the SDK, or any other method for that matter?

    I see the power of SCOM for the ability to store relational system information. I would like the ability to "Manually" discover instances by statically setting Instance properties and creating relationships then disabling any monitoring.

    If I could do this, then I could use the Console UI to show me, visually, the relationships between various instances and their properties without having to deploy agents into my environment to automatically discover it.

    I have tried to create singleton classes that inherit from classes I want to instantiate but I get errors that the parent class was not also a singleton.

    Any help would be great.

    Thanks,

    Tony

  66. tonyh413 says:

    Wow, how did I miss that?  Thanks.

  67. sstranger says:

    Hi Jakub,

    I’m trying to associate a Run As Account with a specific monitor I created. But it’s still not working ;-( According to my debug info the script is still running under the local system account and not under the specified run as account.

    These are the steps I’ve taken:

    1. Created a MP with the monitor in it. I’ve added some debug info, like the account under which the script has run. This info is written to the OpsMgr eventlog.

    2. Added a SecureReference in the MP.

    3. Added SecureInput in the MP after Scriptbody

    4. Added DisplayString for the Run As Profile (SecureReference)

    5. Created a Run As Account using a domain account for which I tested if the vbscript used in the monitor will run correctly.

    6. Imported the MP.

    7. Added the Run As Account to the Run As Profile for the computer I want to monitor.

    I am not sure what you meant with using Password = wscript.StdIn.ReadLine()

    Is this needed in the vbscript or should the script just run under the run as account?

    I’ve saved the mp as pdf and you can find it here: http://cid-3ac99c5995164f2b.skydrive.live.com/self.aspx/files/Test.BizTalk.MP.pdf

    Thanks for your help.

    Regards,

    Stefan

  68. In order to have the script run as a particular user, you need to set the RunAs attribute on the unit monitor to the secure reference you want to use.

    The secure input will pass the password into the script as a parameter.

  69. sstranger says:

    Hi Jakub,

    I’ve added the RunAs attribute on the unit monitor.

    <UnitMonitor ID="UIGeneratedMonitorbf1283cc99634f39b46d76f5adc0f26f" Accessibility="Public" Enabled="true" Target="UINameSpace126a3abb20064e299a8f440831ada258.Group" ParentMonitorID="Health!System.Health.AvailabilityState" Remotable="true" Priority="Normal" TypeID="Windows!Microsoft.Windows.TimedScript.TwoStateMonitorType" ConfirmDelivery="false" RunAs="BizTalk.Monitor.RunAsAccount">

    But that still didn’t do the trick. I’m not able to use the secure input to pass the password and useraccount into the script as a parameter because in the script I’m using a WMI query. And according to info on the internet I found out that for WMI you cannot specify a user and password argument for the local connection as local connections always use the logged in user’s credentials.

    Any ideas? I would like to have the complete script run under the specified RunAs account.

    Regards,

    Stefan Stranger

  70. So when you did this, what did not work? The monitor should have run as the user you have configured for the BizTalk.Monitor.RunAsAccount.

  71. sstranger says:

    Hi Jabuk,

    You were right it did work! Someway after the re-import of the MP the Run As Account had to be added again to the Run As Profile for the computer I wante to monitor. Then I worked!

    I’ll post a Guide on my weblog (http:\weblog.stranger.nl) how I did soon.

    Thanks for your help!

    Regards,

    Stefan Stranger

  72. michelk says:

    Jakub,

    I’m planning to make a utilization performance collection rule for a Cisco switch device.

    Collect 1 sample . Wait 60 sec. Collect the second sample . Compute the utilization using sample 1 and 2. Write to ops db.

    I have seen that SCOM has no build in modules for this. Correct me if wrong.

    I was thinking of making a Condition Detection that has the 2 sample values as data input and in this module I calculate the utilization and output a performance output type. Must I do this with a outside C# module. Or can I use basic vbscript for the calculation.  

    What would you do to get this working. ?

    michel

  73. I don’t know how to do this but I am trying to find out.

  74. michelk says:

    Ok , Thanks for your time.

    Please let me know if you have found out something.

    Michel

  75. According do a developer on our team, he says we have a module that will allow for computing the average of N number of samples. If you want something other than average, you either need to write a script or your own module.

  76. michelk says:

    Thanks for replying,

    The AVG module is not usably for this. Almost all SNMP devices work with incremental counters. So value T1 will always be > then value T2. To calculate the utilization I must do a manual calculation with T2 and T1.

    But as you mentioned I must write a own module. Would you write a "Condition Detection" module ? or would you write a "Datasource" module.

    Michel

  77. If you are going to go the module route, you would most likely go with condition detection, although data source would work fine too (if you wanted to read the data from the source yourself).

  78. michelk says:

    Ok. i haved looked at the "Condition Detection" module (with the extended authoring console). But when I want to choose the module type I can’t see any condition dectection type that uses a script. I even traced back the system.performance.deltavaluecondition to see how this is done. But this module refers to a assembly.

    So my questions are:

    – Can you give me a example or direction how to create a condition dection module that uses a (vb)script.

    – How can i create a assembly (c# ?) that i can use in a module type ?

    Thanks again for your help.

    Michel

  79. Sorry, I thought you were referring to writing your own module. For scripts, I believe only a write action is supported. Unfortunately, I don’t know much about the script API or how you can leverage it to accomplish what you want. The OpsMgr public forums may be a better bet.

    For writing your own, largely, this is not supported. We don’t have many docs about it nor did we mean this to be a public scenario. In some rare cases for partners we do support it, but outside of that we recommend using scripts when possible.

  80. michelk says:

    I have tried many scenarios for now. But i can’t get it to work with the supplied modules.

    You mentioned the support in rare cases for partners. We are gold partner and SCOM 2007 is our main business. We sell hosted monitoring based on MOM 2005 and in 2008 based on SCOM 2007. I’m developing the management packs for non-Microsoft products as VMWare , Orcale , Unix , UPS , Printers and Network Routers etc. Now I’m in the middle of reprogramming the Cisco/HP network routers management pack. That’s why I asked you about the utilization module. Is there a way to get this documentation to write my own utilization ‘condition detection’ module. ?

  81. Shoot me a direct mail using the link on the right and I will put you in touch with the proper person on our team.

  82. michelk says:

    Okay,  Ive PM’d you.

    michel

  83. jdpickering says:

    Question on WMI Event Monitoring and I might just be doing this wrong can i use the Default Templates for WMI event for this example?  I’m trying to setup a Exchange 2003 WMI based monitor to keep an eye on a queue.  I created a monitor i’ve set the namespace to RootMicrosoftExchangeV2 and my first query is SELECT *

    FROM Exchange_SMTPlink

    WHERE LinkName = "SpamWall" with a expression of StateRetry = TRUE and then my send query is the same just the expression is different StateReady = TRUE.  What I am trying to do is when it performs this query if StateRetry = True go Unhealthy and when StateReady = TRUE go Healthy is this correct.

  84. Please post your question to the newgroups, probably microsoft.public.opsmgr.authoring or microsoft.public.opsmgr.managementpacks. Unfortunately, this is outside my area of expertise.

  85. Weddings says:

    Well, it has been quite a holiday! My wife delivered our son, Jamison Jakub, on December 26th at 8:14 AM. Mom and baby are doing great. I’ve posted some photos on our families personal site: http://www.oleksyfamily.com . I am more or less back at work for no

  86. Chethan Thopaiah says:

    I have a sealed MP and I have to override a discovery config called "Frequency" and save it in the default MP. Can somebody post a code snippet for this?