diff --git a/cli/Commands/Cronjobs/CronjobExecute.php b/cli/Commands/Cronjobs/CronjobExecute.php
index 23592a1bac9af9decf84b55c97a0697984744182..d4789ea84ba58af141e52b8912612b8982b4f85c 100644
--- a/cli/Commands/Cronjobs/CronjobExecute.php
+++ b/cli/Commands/Cronjobs/CronjobExecute.php
@@ -5,7 +5,11 @@ namespace Studip\Cli\Commands\Cronjobs;
 use Symfony\Component\Console\Command\Command;
 use Symfony\Component\Console\Input\InputArgument;
 use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
 use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Question\ChoiceQuestion;
+use Symfony\Component\Console\Question\ConfirmationQuestion;
+use Symfony\Component\Console\Question\Question;
 
 class CronjobExecute extends Command
 {
@@ -15,28 +19,115 @@ class CronjobExecute extends Command
     {
         $this->setDescription('Execute cronjob task.');
         $this->setHelp('This command will execute a cronjob task.');
-        $this->addArgument('task_id', InputArgument::REQUIRED, 'Id of the desired cron job');
+
+        $this->addArgument(
+            'task_id',
+            InputArgument::OPTIONAL,
+            'Id of the desired cron job'
+        );
+
+        $this->addOption(
+            'input',
+            'i',
+            InputOption::VALUE_NONE,
+            'Interactively input values (defaults to true if no task_id is given)'
+        );
     }
 
     protected function execute(InputInterface $input, OutputInterface $output): int
     {
+        $helper = $this->getHelper('question');
         $task_id = $input->getArgument('task_id');
+
+        $input_values = $task_id === null || $input->getOption('input');
+
+        if ($task_id === null) {
+            $question = new ChoiceQuestion(
+                "\nWhich cronjob should be executed:\n",
+                $this->getCronjobTaskList()
+            );
+            $task_id = $helper->ask($input, $output, $question);
+        }
+
         $task = \CronjobTask::find($task_id);
         if (!$task) {
             $output->writeln('<error>Unknown task id</error>');
             return Command::FAILURE;
         }
-        if (!file_exists($GLOBALS['STUDIP_BASE_PATH'] . '/' . $task->filename)) {
-            $output->writeln(sprintf('<error>Invalid task, unknown filename %s</error>', $task->filename));
+        if (!$task->valid) {
+            $output->writeln(sprintf(
+                '<error>Invalid task, unknown filename %s or invalid class %s</error>',
+                $task->filename,
+                $task->class
+            ));
             return Command::FAILURE;
         }
-        require_once $GLOBALS['STUDIP_BASE_PATH'] . '/' . $task->filename;
-        if (!class_exists('\\' . $task->class)) {
-            fwrite(STDOUT, 'Invalid task, unknown class "' . $task->class . '"' . PHP_EOL);
-            $output->writeln(sprintf('<error>Invalid task, unknown class %s</error>', $task->class));
-            return Command::FAILURE;
+
+        $parameters = $this->getDefaultTaskParameters($task);
+
+        if ($input_values && count($parameters) > 0) {
+            $output->writeln("\nParameters:\n");
+
+            foreach ($task->parameters as $key => $definition) {
+                $description = trim($definition['description'], ' ?');
+                $default = trim(json_encode($definition['default'] ?? null), "'");
+                $label = " > {$description} [<comment>{$default}</comment>] : ";
+
+                if ($definition['type'] === 'boolean') {
+                    $question = new ConfirmationQuestion(
+                        $label,
+                        $definition['default'],
+                        '/^(y|j|1)/i'
+                    );
+                } elseif ($definition['type'] === 'select' && !empty($definition['values'])) {
+                    $question = new ChoiceQuestion(
+                        $label,
+                        $definition['values']
+                    );
+                } else {
+                    $question = new Question(
+                        $label,
+                        $definition['default']
+                    );
+                    if ($definition['type'] === 'integer') {
+                        $question->setNormalizer(function ($value) {
+                            return $value ? trim($value) : '';
+                        })->setValidator(function ($value): int {
+                            if (strlen($value) && !ctype_digit($value)) {
+                                throw new \RuntimeException('Number is invalid.');
+                            }
+                            return $value;
+                        });
+                    }
+                }
+                $parameters[$key] = $helper->ask($input, $output, $question);
+            }
         }
-        $task->engage('');
+
+        $task->engage('', $parameters);
+
         return Command::SUCCESS;
     }
+
+    protected function getCronjobTaskList(): array
+    {
+        $result = [];
+        \CronjobTask::findEachBySQL(
+            function (\CronjobTask $task) use (&$result): void
+            {
+                $result[$task->id] = $task->name;
+            },
+            '1'
+        );
+        return $result;
+    }
+
+    private function getDefaultTaskParameters(\CronjobTask $task): array
+    {
+        $parameters = [];
+        foreach ($task->parameters as $key => $definition) {
+            $parameters[$key] = $definition['default'] ?? null;
+        }
+        return $parameters;
+    }
 }
diff --git a/cli/Commands/Cronjobs/CronjobList.php b/cli/Commands/Cronjobs/CronjobList.php
index 4afa637b12a8ba0caf139a9224f242c43a264587..3506276bcde4ffbe031e2161571961e5c9dc8ed9 100644
--- a/cli/Commands/Cronjobs/CronjobList.php
+++ b/cli/Commands/Cronjobs/CronjobList.php
@@ -27,7 +27,7 @@ class CronjobList extends Command
             $table->setStyle('compact');
             $table->setHeaders(['Task-ID', 'Description']);
             foreach ($tasks as $task) {
-                if (!class_exists($task->class)) {
+                if (!$task->valid) {
                     continue;
                 }
                 $description = call_user_func(['\\' . $task->class, 'getDescription']);
diff --git a/lib/models/CronjobTask.class.php b/lib/models/CronjobTask.class.php
index 754041660b80cc02812668e6b8f53df73e35b37f..5b5350f8c0368839d03154f21c849dcd5e5d80f9 100644
--- a/lib/models/CronjobTask.class.php
+++ b/lib/models/CronjobTask.class.php
@@ -35,6 +35,10 @@
  * @property string execution_count database column
  * @property string assigned_count database column
  * @property SimpleORMapCollection schedules has_many CronjobSchedule
+ *
+ * @property string $description
+ * @property string $name
+ * @property array $parameters
  */
 class CronjobTask extends SimpleORMap
 {