Your data is not laid out such that this is directly possible. As soon as you start talking about combining records or making queries across records then you need an organizational structure in place. For your specific scenario you're going to need to group the students by the courses (to get the hierarchy) and then order the groups according to your course rules. Then you'll need to order the students within each course. Something like this might work.
var groups = from s in students
group s by s.CourseName into g
select new {
CourseName = g.Key,
WeightedScore = g.Sum(x => x.FinalGrade * x.GradeFactor),
TotalStudents = g.Count(),
Students = g.ToArray()
};
var ordered = groups.OrderByDescending(x => x.TotalStudents).ThenByDescending(x => x.WeightedScore);
foreach (var group in ordered)
foreach (var student in group.Students.OrderByDescending(s => s.FinalGrade).ThenByDescending(s => s.GradeFactor).ThenBy(s => s.StudentID))
Console.WriteLine(student.StudentID);
But if you reorganized your data such that courses contained students then you could simplify the grouping and just be left with the ordering.