Verwenden des Taskschedulers zum Starten mit anderen Credentials

Unter bestimmten Umständen kann es nötig sein einen Task für einen bestimmten Userkontext einzurichten und auch gleich auszuführen.

Ab Windows 6 (Vista und Windows Server 2008) gibt es für den Scheduler eine schöne API (Task Scheduler Referenz in der msdn), die unter C# als Verweis auf das Com-Objekt hinzugefügt werden kann.

Hier mal ein kleines Beispiel, wie der Task erstellt wird, mit ACLs versehen, gestartet und auf das Ergebnis gewartet wird und anschliessend wieder gelöscht wird:

#using Taskscheduler

string strTaskname = "Task1";
//erstmal connect zum Scheduler und zum Rootfolder
var scheduler = new TaskSchedulerClass();
scheduler.Connect(null, null, null, null);
ITaskFolder rootfolder = scheduler.GetFolder("\\");

//Löschen des alten Task, falls er noch existieren sollte
try
{
   IRegisteredTask task_old = rootfolder.GetTask(strTaskname);
   rootfolder.DeleteTask(strTaskname, 0);
}
catch (FileNotFoundException)
{
   Console.WriteLine("alter Task nicht mehr vorhanden - OK");
}

// Anlegen eines neuen Task
ITaskDefinition taskdef = scheduler.NewTask(0);
IRegistrationInfo regInfo = taskdef.RegistrationInfo;
regInfo.Description = "Beschreibung fuer den Task";
regInfo.Author = "me";
// Ausfuehrung soll mit den höchsten Privilegien stattfinden
taskdef.Principal.RunLevel = _TASK_RUNLEVEL.TASK_RUNLEVEL_HIGHEST;
// Task wird unsichtbar (falls gewünscht)
taskdef.Settings.Hidden = true;

// Anlegen einer Aktion (für das Ausführen eines Programms)
IExecAction action = (IExecAction)taskdef.Actions.Create(_TASK_ACTION_TYPE.TASK_ACTION_EXEC);
action.Path = Path.Combine(TargetPath, "ToDo.exe");
action.Arguments = "/param1 /param2";
action.WorkingDirectory = "C:\\TEMP";

// Task im Scheduler registieren
IRegisteredTask task = rootfolder.RegisterTaskDefinition(strTaskname, taskdef, 6, "Domain\\userid", "geheimesPasswort", _TASK_LOGON_TYPE.TASK_LOGON_PASSWORD, "");

// Setzen von Zugriffsrechten auf den Task
string strSDDL = task.GetSecurityDescriptor(4);
strSDDL += "(A;;FA;;;SY)"; // weitere gewünschte Zugriffsrechte
task.SetSecurityDescriptor(strSDDL, 0);

// Jetzt mal schauen, was wir so erzeugt haben
Console.WriteLine("Erstellter Task: " + task.Name);
Console.WriteLine("Status des Tasks: " + task.State);
if (task.State != _TASK_STATE.TASK_STATE_READY)
{
   Console.WriteLine("Status des Tasks lässt keine Ausführung zu");
   rootfolder.DeleteTask(strTaskname, 0);
   throw (new Exception("Task hatte falschen Status nach dem Erstellen"));
}

// Jetzt starten wir unseren Task
Console.WriteLine("Starten des Tasks ...");
IRunningTask rtask = task.Run(null);
// Erstmal ein bisschen warten (Zeit kann auch kürzer sein)
System.Threading.Thread.Sleep(25000);
Console.WriteLine("Status unseres Tasks: " + task.State);
Console.WriteLine("Status unseres gestarteten Tasks: " + rtask.State);
while (rtask.State == _TASK_STATE.TASK_STATE_RUNNING ||
rtask.State == _TASK_STATE.TASK_STATE_QUEUED)
{
   Console.WriteLine("Task noch nicht beendet (Status: " + rtask.State + ") -> 15 Sekunden warten");
   System.Threading.Thread.Sleep(15000);
   rtask.Refresh();
}
Console.WriteLine("Status unseres Tasks: " + task.State);
// Schauen wir mal, was wir so zurückbekommen haben
Console.WriteLine("Returncode des Tasks: " + task.LastTaskResult);

Console.WriteLine("Löschen des Tasks ...");
rootfolder.DeleteTask(strTaskname, 0);

2 thoughts on “Verwenden des Taskschedulers zum Starten mit anderen Credentials”

Schreibe einen Kommentar

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s