Disabling Workflows with Overrides

Disabling Workflows with Overrides

  • Comments 7
  • Likes

I’ve had a few customers and partners ask how they can disable our out of box workflows so they can implement their own custom workflow logic in their own code.  It’s actually really easy to do with a little “know how” and some XML editing.  If you are going to use this technique to disable workflows that we provide out of the box, please be aware that we have not specifically tested that scenario and you should thoroughly test out what the impact is of disabling these workflows are on your system and processes before you try this in a production environment.

Usually customers and partners want to disable our change request related workflows when they want to do something like this so I’ll provide the example of disabling the workflow that changes a CR status from New to In Progress as my example.  This behavior happens as a result of either the New Change Request or the Activity Added workflow running so in the example I will show how to disable both of them with an override.

For those of you with a background in SCOM you are probably already familiar with overrides.  Overrides allow you to override the configuration of workflows – rules, monitors, and runtime tasks.  You can override parameters like scheduled intervals, thresholds, etc using this technique but in this case what we want to do is override the Enabled property.

To do this we first need to identify which rules we want to disable and which MPs those rules are in.  To do this I ran a query like this in the ServiceManager database:

select * from rules where rulename like '%change%' or rulename like '%activity%'

You can also find the rule name using the Get-SCSMRule cmdlet in SMLets if PowerShell is more your thing than T-SQL.

You also need to know the management pack ID, public key token, and version that the rule(s) are contained in because we are going to need to create references to those MPs.  To do that just grab the ManagementPackId GUID from the query results:

image

And run a query like this:

select MPName, MPVersion, MPKeyToken from managementpack where managementpackid = '2BF6413B-BB6C-1108-D33A-152C9D1DB56B'

image

Now we just need to create a new management pack and reference the System.Library and ServiceManager.ChangeManagement.Library management packs.  Then we just add the Monitoring section, add an Overrides section inside of there and declare each of our RulePropertyOverride elements:

<ManagementPack xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" ContentReadable="true" SchemaVersion="1.1" OriginalSchemaVersion="1.1">
  <Manifest>
    <Identity>
      <ID>Microsoft.Demo.Overrides</ID>
      <Version>1.0.0.0</Version>
    </Identity>
    <Name>Override Demo</Name>
    <References>
      <Reference Alias="System">
        <ID>System.Library</ID>
        <Version>7.0.6555.0</Version>
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
      <Reference Alias="ChangeLibrary">
        <ID>ServiceManager.ChangeManagement.Library</ID>
        <Version>7.0.6555.0</Version>
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
      </Reference>
    </References>
  </Manifest>
  <Monitoring>
    <Overrides>
      <RulePropertyOverride ID="DisableNewChangeRequestRule" Context="System!System.Entity" Enforced="false" 
Rule="ChangeLibrary!ServiceManager.ChangeManagement.NewChangeRequestRule" Property="Enabled">
        <Value>false</Value>
      </RulePropertyOverride>
      <RulePropertyOverride ID="DisableActivityAddedRule" Context="System!System.Entity" Enforced="false" 
Rule="ChangeLibrary!ServiceManager.ChangeManagement.ActivityAddedRule" Property="Enabled">
        <Value>false</Value>
      </RulePropertyOverride>
    </Overrides>
  </Monitoring>
  <LanguagePacks>
    <LanguagePack ID="ENU" IsDefault="true">
      <DisplayStrings>
      <DisplayString ElementID="Microsoft.Demo.Overrides">
        <Name>Override Demo</Name>
      </DisplayString>
      </DisplayStrings>
    </LanguagePack>
  </LanguagePacks>
</ManagementPack>
Just to explain a little bit what is going on here:
  • the ID attribute can be anything.  It just needs to be unique within the MP.
  • the Context attribute should always point at the System.Entity in SCSM.  It’s just the easiest thing to do to ensure it is always disabled.
  • the Enforced attribute should generally always be set to ‘false’.  That allows other overrides which are marked Enforced = ‘true’ to override this override.
  • The Rule attribute should point to the rule name of the rule you want to override the property for.  Here, I used an MP reference alias in front of the rule name since the rule is in another MP.
  • The Property attribute needs to be the name of the property – in this case we want to override the Enabled property value.
  • The Value element contains the override value. In this case we use false to disable the rule by setting its Enabled property to false.
 
Now, we can just import this MP into SCSM and disable those two rules.  To re-enable them just delete the MP.
I’ve attached the demo MP for this below.
Attachment: Microsoft.Demo.Overrides.xml
Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • Hi !

    Can i override Rule priority like this?

    <RulePropertyOverride ID="DelayActivityStatusChangedRule" Context="System!System.Entity" Enforced="false" Rule="ChangeLibrary!ServiceManager.ChangeManagement.ActivityStatusChangedRule" Property="Priority">

     <Value>0</Value>

    </RulePropertyOverride>

    I am getting error while importing the management pack, saying that property Priority is incorrect...

  • @Kirill - what is the scenario you are trying to achieve?

  • Travis, I am trying to do something like this. I have created change request template with several activities (some of them custom classes, some manual activity, some review activities). I need some activities from this sequence to be skipped (not be in progress state), if some criteria meets. For example, in Activity1 if custom field is selected, then next Activity2 is not needed, and Activity3 should be in progress state. So i have achieved this. I created additional state for activity (named "Skipped"), and created workflow "SetSkipped", with triggers when Activity1 is completed. That workflow (smlets powershell script) checks if field is selected, and if so sets Activity2 to "Skipped" state, And Activity3 to "In progress". Everything works fine, but there is some problem. I have also created notification workflows, when Activities enter "In Progress". That workflows send email to implementer of this activity. So when i test my scenario, Activity2 enters in "Skipped" state, but implementer of Activity2 anyway recieves email. I think it happens because my workflow "SetSkipped" runs AFTER built-in workflow (i think ActivityStatusChangedRule). So i need my workflow "SetSkipped" runs first. I try to change polling interval of "SetSkipped" to 1second, but no happy :(

    I hope you will tell me some advices how to achieve my senario. Thank you.

  • It sounds like you are currently triggering your SetSkipped workflow when the status of Activity 1 changes.  Is that right?

  • Yes. The workflow "SetSkipped" triggers when Activity1 changes status to Completed. But in practice, when Activity1 is completed, then Activity2 has time to changes status to In progress (by built-in workflow i think ActivityStatusChangedRule ) and after that changes status to Skipped (by SetSkipped). I can see it at history tab in activity2. That behavior triggers notification email to implementer about Activity2 (which action not needed). That is my problem. If i can take priority of workflows, that my workflow Setskipped runs first.

  • @Kirill -

    It could work a little bit better if you trigger your workflow not on the status property change but on the property value change instead.  For example you had this requirement:

    "in Activity1 if custom field is selected, then next Activity2 is not needed"

    If you trigger your workflow when Activity.CustomField property changes then it will trigger the workflow and make activity 2 not needed.  Of course if the custom field property change happens at the same time as the status change you will still have this problem.  You could try to train your users to change the property value and submit before submitting the status.

    Another option is to only ADD activities to the process based on the user's selections and not try to remove.  This might be a little trickier but would be more predictable.