Your situation
Sometimes the best way to solve a problem is to avoid it. Why not make Status a property on Task rather than a return value? Then you can just check the status of each sub-task before ticking, and skip it if its status is SUCCESS
In General
You're along the right lines in identifying that IEnumerable and IEnumerator are very powerful concepts that can often help you in situations like this. However, having to directly deal with an IEnumerator is usually annoying- that's why things like IEnumerable, foreach and yield are there. In this case, consider a wrapper class:
class OneTimeEnumerable<T> : IEnumerable<T>
{
private IEnumerator<T> _inner;
public OneTimeEnumerable(IEnumerable<T> source)
{
_inner = source.GetEnumerator();
}
public IEnumerator<T> GetEnumerator()
{
return _inner;
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
All this does is give you an IEnumerable<T> which always returns the same enumerator back (with its Current in the same position), rather than a new one each time. Then you can store this, and foreach over it as usual, rather than having to deal with too-low-level things like MoveNexts.
Note, by the way, that I'm using the generic IEnumerator and IEnumerable. You should pretty much always do this, in the same way that you'd always choose to use a List<Task> to hold tasks rather than a List<object>
Etc.
For more general comments, your code is mostly good stylistically. Naming conventions, actual names, and so on, are good ("Sequencer" is possibly a little iffy, but I can't be sure without knowing exactly what it does differently from other potential CompositeTask implementations)
Two ways in which your code doesn't follow standard C# conventions is your use of all-uppercase for enum values, and having opening braces on the same line. Both of these are a matter of preference, but it's usually a good idea to follow language conventions.