Tasks are very poorly documented in MP authoring guides, nevertheless I think they’re really useful in automating queries and diagnostics an operator would have to perform locally on the agent. This is the third article on tasks, the previous two have been:
In this installment I will recap what I learned on command executer based tasks, especially in terms or returning a meaningful output to the operator.
This could seem obvious, but when I started to develop agent based task I observed the following:
- my task always returned in success regardless of the command exit code
- failed tasks, returned in success but showed no output
- the only way to differentiate from a successful task and a broken is to check is nay output was returned
I would say not satisfactory at all. Since there’s no specific topic on task creation in standard documentation (at least I haven’t been able to find one), I started from the roots, reading all the documentation about the System.CommandExecuter* modules. The key topic is the CommandExecuterEventPolicyType documentation where you can read:
"If a module is used by a task, the default behavior is that all states, except fatal error, are marked as being successful task execution. This means that a script could fail during execution of a task, but Operations Manager would report the task as succeeding, which can be confusing to the user." (http://msdn.microsoft.com/en-us/library/ee809320.aspx)
The Severity tag is the key:
Severity = 0 – Task always return in success (if execution is able to start) and returns the full stdout/stderr/exit code messages. So if you want to fail your script and return an error message in stdout this the way you can have it displayed.
Severity = 1 – Default. Task always return in success (if execution is able to start), but if the command output matches the failure policy, no output is retuned. This default is not thought for Tasks, and it needs to be changed.
Severity = 2 – The task returns in error if the policy matches but no output from the command is returned, just the piece of info that matches the policy. For example if the match is on the exit code, only the exit code is returned with some workflow info (command line etc.) but stdout is not returned.
Given the evidence that Severity=1 is useless for tasks, here we have two choices:
- always return in success and show the stdout stream – great so that you have the complete output with the error message in case of any error, but terrible if you’re executing a task against a set of objects: all the tasks return success even if some of them have failed, you need to step on every task to see which of them as failed and which terminated in success
- break in error, forget about stdout stream, and show the stderr output of your command. As I stated before only the piece of info that matches the policy is shown, the evaluation order is stdout, stderr, exit code. So if in case of error you write to stderr that message will reach the OpsMgr console.
The following is a task with <Severity>2</Severity> and a match on the exit code (not very useful, isn’t it?)
But if you manage to write into stderr then you can return more info to the operator
So my choice, for command executer based task, is to set Severity to 2 and write to stderr anytime the task needs to return in error.
How all this translates in MP authoring?
Let’s take two samples:
- A standard script based task (Microsoft.Windows.ScriptProbeAction)
- A custom Command Executer Probe based task
In both samples I use a Probe type, but a Write Action would behave exactly the same.
The default event policy has for this probe has Severity=1, so we’re in trouble, but the probe exposes the <EventPolicy> configuration (rarely used indeed in all MPs) and this one does the trick:
In this snippet you can notice how to write to stderr from a vbscript (just in case you forgot it).
Custom Command Executer
In this case we can define a more appropriate event policy directly in the probe type, the basic composition would be like this:
This is a standard ProbeAction based on a CommmandExecuterProbe where I have overridden the DefaultEventPolicy setting Severity=2 and exposing the EventPolicy configuration just in case any task would need to set it to a different value.
If you need to return meaningful output from your tasks in case of error, just remember the EventPolicy tag. Many standard MPs completely forgot to do this causing a very confusing experience for operators.
This posting is provided "AS IS" with no warranties, and confers no rights.