Table of Contents

Find overridden job variables

This script looks at all groups, jobs, and steps to find places where Job Variables defined at a higher level have been overridden.

The script finds all places where a group, job, or step overrides a variable that is defined at a higher level (server, group, queue, or job).

The script does not compare the variable value to the higher-level value: it only checks whether the variable has been defined at the lower level. That is, if a group has variable "Environment" defined as "Production" and a job in the group has variable "Environment" defined as "Production" that is still reported as an override, because the job has an explicit value for the variable, and if the variable is changed at the group level the job will not get the new value.

void Main()
{
    using (var session = Scheduler.Connect(".", LoginAuthenticationType.Windows, "", ""))
    {
        using (var context = session.NewDataContext())
        {

            //create a dictionary to track the variables we have seen and the location where we saw each
            var seenVariables = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

            //add the server-level variables
            AddVariables(seenVariables, context.GetServerSettings().JobVariables, "Server");

            //fetch the root group
            var root = context.GetJobGroup(null);
            
            //go look for overrides
            CheckVariables(root, seenVariables);
        }
    }
}


//copy variables from a JobVariableCollection to the seenVariables dictionary
void AddVariables(Dictionary<string,string> target, ArcanaDevelopment.adTempus.Client.Collections.JobVariableCollection source, string location)
{
    //we don't care about the value of the variable in this dictionary; we store the location where the variable was defined.
    foreach(var item in source)
    {
        target[item.Name] = location;
    }	
}


//check variables in a group (and children) for overrides
void CheckVariables(JobGroup group,Dictionary<string,string> parentSeenVariables)
{
    var location = string.Format("Group \"{0}\"", group.FullyQualifiedName);

    //check for variables overridden at this level
    CheckVariables(group.JobVariables, parentSeenVariables, location);
    
    //make a copy of the seenVariables from the parent level(s) so we can add new variables from this level
    var seenVariables = parentSeenVariables.ToDictionary(entry => entry.Key,entry => entry.Value,StringComparer.OrdinalIgnoreCase);
    
    //add the variables from this level to the seenVariables collection
    AddVariables(seenVariables, group.JobVariables, location);

    //check all the jobs in this group
    var jobs=group.GetJobs(ObjectFetchOptions.FullFetch,false);
    foreach(var item in jobs)
    {
        CheckVariables(item,seenVariables);	
    }
    
    //check the child groups
    var childGroups=group.GetGroups(ObjectFetchOptions.FullFetch,false);
    foreach(var item in childGroups)
    {
        CheckVariables(item,seenVariables);
    }
}

//checks to see if a job or its steps override variables defined at a higher level
void CheckVariables(Job job,Dictionary<string,string> parentSeenVariables)
{
    //make a copy of the seenVariables from the parent level(s)
    var seenVariables = parentSeenVariables.ToDictionary(entry => entry.Key, entry => entry.Value, StringComparer.OrdinalIgnoreCase);
    
    //add the variables from the job's Queue so we can see if the job has overridden any of those
    AddVariables(seenVariables, job.JobQueue.JobVariables, string.Format("Job Queue \"{0}\"",job.JobQueue.Name));
    
    var location=string.Format("Job \"{0}\"",job.FullyQualifiedName);
    
    //see if the job has overridden anything
    CheckVariables(job.JobVariables,seenVariables,location);


    //add the job's variables to the list so we can see if the steps override them
    AddVariables(seenVariables, job.JobVariables, location);

    //check the steps
    foreach(var item in job.Steps)
    {
        CheckVariables(item.JobVariables, seenVariables, string.Format("Job \"{0}\" step {1}", job.FullyQualifiedName,item.StepNumber));
    }
}

//checkes to see if any item in a JobVariableCollection overrides variables defined at a higher level
void CheckVariables(ArcanaDevelopment.adTempus.Client.Collections.JobVariableCollection variables, Dictionary<string, string> seenVariables, string locationDescription)
{
    foreach (var item in variables)
    {
        string seenLocation;

        if (seenVariables.TryGetValue(item.Name, out seenLocation))
        {
            WriteOutput(string.Format("{0} overrides variable \"{1}\" from {2}", locationDescription, item.Name, seenLocation));
        }
        else
        {
            seenVariables.Add(item.Name, locationDescription);
        }
    }
}

void WriteOutput(string output)
{
    Debug.WriteLine(output);	
}

See Also