Index: core/admin_templates/scheduled_tasks/scheduled_task_list.tpl
===================================================================
--- core/admin_templates/scheduled_tasks/scheduled_task_list.tpl
+++ core/admin_templates/scheduled_tasks/scheduled_task_list.tpl
@@ -51,16 +51,6 @@
 
 				a_toolbar.AddButton(
 					new ToolBarButton(
-						'process',
-						'<inp2:m_phrase label="la_ToolTip_Run" escape="1"/>',
-						function() {
-							submit_event('scheduled-task', 'OnRun');
-						}
-					)
-				);
-
-				a_toolbar.AddButton(
-					new ToolBarButton(
 						'cancel',
 						'<inp2:m_phrase label="la_ToolTip_Cancel" escape="1"/>',
 						function() {
@@ -94,6 +84,6 @@
 
 <inp2:m_RenderElement name="grid" PrefixSpecial="scheduled-task" IdField="ScheduledTaskId" grid="Default"/>
 <script type="text/javascript">
-	Grids['scheduled-task'].SetDependantToolbarButtons( new Array('edit','delete', 'approve', 'decline', 'process', 'cancel') );
+	Grids['scheduled-task'].SetDependantToolbarButtons( new Array('edit','delete', 'approve', 'decline', 'cancel') );
 </script>
-<inp2:m_include t="incs/footer"/>
\ No newline at end of file
+<inp2:m_include t="incs/footer"/>
Index: core/install/cache/class_structure.php
===================================================================
--- core/install/cache/class_structure.php
+++ core/install/cache/class_structure.php
@@ -88,6 +88,7 @@
 		'Intechnic\\InPortal\\Core\\kernel\\Console\\Command\\IConsoleCommand' => '/core/kernel/Console/Command/IConsoleCommand.php',
 		'Intechnic\\InPortal\\Core\\kernel\\Console\\Command\\ResetCacheCommand' => '/core/kernel/Console/Command/ResetCacheCommand.php',
 		'Intechnic\\InPortal\\Core\\kernel\\Console\\Command\\RunEventCommand' => '/core/kernel/Console/Command/RunEventCommand.php',
+		'Intechnic\\InPortal\\Core\\kernel\\Console\\Command\\RunScheduledTaskCommand' => '/core/kernel/Console/Command/RunScheduledTaskCommand.php',
 		'Intechnic\\InPortal\\Core\\kernel\\Console\\ConsoleApplication' => '/core/kernel/Console/ConsoleApplication.php',
 		'Intechnic\\InPortal\\Core\\kernel\\Console\\ConsoleCommandProvider' => '/core/kernel/Console/ConsoleCommandProvider.php',
 		'Intechnic\\InPortal\\Core\\kernel\\Console\\IConsoleCommandProvider' => '/core/kernel/Console/IConsoleCommandProvider.php',
@@ -887,6 +888,14 @@
 				1 => 'Stecman\\Component\\Symfony\\Console\\BashCompletion\\Completion\\CompletionAwareInterface',
 			),
 		),
+		'Intechnic\\InPortal\\Core\\kernel\\Console\\Command\\RunScheduledTaskCommand' => array(
+			'type' => 1,
+			'modifiers' => 0,
+			'extends' => array(
+				0 => 'Intechnic\\InPortal\\Core\\kernel\\Console\\Command\\AbstractCommand',
+				1 => 'Stecman\\Component\\Symfony\\Console\\BashCompletion\\Completion\\CompletionAwareInterface',
+			),
+		),
 		'Intechnic\\InPortal\\Core\\kernel\\Console\\ConsoleApplication' => array(
 			'type' => 1,
 			'modifiers' => 0,
Index: core/kernel/Console/Command/RunScheduledTaskCommand.php
===================================================================
--- /dev/null
+++ core/kernel/Console/Command/RunScheduledTaskCommand.php
@@ -0,0 +1,116 @@
+<?php
+/**
+* @version	$Id$
+* @package	In-Portal
+* @copyright	Copyright (C) 1997 - 2015 Intechnic. All rights reserved.
+* @license      GNU/GPL
+* In-Portal is Open Source software.
+* This means that this software may have been modified pursuant
+* the GNU General Public License, and as distributed it includes
+* or is derivative of works licensed under the GNU General Public License
+* or other free or open source software licenses.
+* See http://www.in-portal.org/license for copyright notices and details.
+*/
+
+namespace Intechnic\InPortal\Core\kernel\Console\Command;
+
+
+use Stecman\Component\Symfony\Console\BashCompletion\Completion\CompletionAwareInterface;
+use Stecman\Component\Symfony\Console\BashCompletion\CompletionContext;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+defined('FULL_PATH') or die('restricted access!');
+
+class RunScheduledTaskCommand extends AbstractCommand implements CompletionAwareInterface
+{
+
+	/**
+	 * Configures the current command.
+	 *
+	 * @return void
+	 */
+	protected function configure()
+	{
+		$this
+			->setName('scheduled-task:run')
+			->setDescription('Runs scheduled task(-s)')
+			->addArgument(
+				'scheduled_task_name',
+				InputArgument::OPTIONAL,
+				'Scheduled task name'
+			);
+	}
+
+	/**
+	 * Executes the current command.
+	 *
+	 * @param InputInterface  $input  An InputInterface instance.
+	 * @param OutputInterface $output An OutputInterface instance.
+	 *
+	 * @return null|integer
+	 */
+	protected function execute(InputInterface $input, OutputInterface $output)
+	{
+		$scheduled_task_name = $input->getArgument('scheduled_task_name');
+
+		if ( !$scheduled_task_name ) {
+			$this->Application->EventManager->runScheduledTasks(true);
+
+			return 0;
+		}
+
+		if ( !in_array($scheduled_task_name, $this->getScheduledTaskNames()) ) {
+			throw new \InvalidArgumentException('Scheduled task "' . $scheduled_task_name . '" not found');
+		}
+
+		$scheduled_tasks = $this->Application->EventManager->getScheduledTasks();
+		$result = $this->Application->EventManager->runScheduledTask($scheduled_tasks[$scheduled_task_name]);
+
+		return $result ? 0 : 64;
+	}
+
+	/**
+	 * Return possible values for the named option
+	 *
+	 * @param string            $optionName Option name.
+	 * @param CompletionContext $context    Completion context.
+	 *
+	 * @return array
+	 */
+	public function completeOptionValues($optionName, CompletionContext $context)
+	{
+		return array();
+	}
+
+	/**
+	 * Return possible values for the named argument.
+	 *
+	 * @param string            $argumentName Argument name.
+	 * @param CompletionContext $context      Completion context.
+	 *
+	 * @return array
+	 */
+	public function completeArgumentValues($argumentName, CompletionContext $context)
+	{
+		if ( $argumentName === 'scheduled_task_name' ) {
+			return $this->getScheduledTaskNames();
+		}
+
+		return array();
+	}
+
+	/**
+	 * Returns scheduled task names.
+	 *
+	 * @return array
+	 */
+	protected function getScheduledTaskNames()
+	{
+		$scheduled_tasks = $this->Application->EventManager->getScheduledTasks();
+
+		return array_keys($scheduled_tasks);
+	}
+
+}
Index: core/kernel/managers/scheduled_task_manager.php
===================================================================
--- core/kernel/managers/scheduled_task_manager.php
+++ core/kernel/managers/scheduled_task_manager.php
@@ -187,6 +187,8 @@
 		$scheduled_task->LoadFromHash($scheduled_task_data);
 
 		$event->redirect = false;
+
+		// The fake MasterEvent is needed so that $event can access $scheduled_task!
 		$event->MasterEvent = new kEvent('scheduled-task:OnRun');
 		$this->Application->HandleEvent($event);
 
@@ -228,4 +230,4 @@
 
 		$scheduled_task_data = array_merge($scheduled_task_data, $fields_hash);
 	}
-}
\ No newline at end of file
+}
Index: core/units/scheduled_tasks/scheduled_task_eh.php
===================================================================
--- core/units/scheduled_tasks/scheduled_task_eh.php
+++ core/units/scheduled_tasks/scheduled_task_eh.php
@@ -29,7 +29,6 @@
 
 			$permissions = Array (
 				'OnMassCancel' => Array ('self' => 'add|edit'),
-				'OnRun' => Array ('self' => 'add|edit'),
 			);
 
 			$this->permMapping = array_merge($this->permMapping, $permissions);
@@ -178,37 +177,6 @@
 		}
 
 		/**
-		 * Runs selected scheduled tasks
-		 *
-		 * @param kEvent $event
-		 */
-		function OnRun($event)
-		{
-			$ids = $this->StoreSelectedIDs($event);
-
-			if ($ids) {
-				$object = $event->getObject( Array ('skip_autoload' => true) );
-				/* @var $object kDBItem */
-
-				$where_clause = Array (
-					$object->TableName . '.' . $object->IDField . ' IN (' . implode(',', $ids) . ')',
-					$object->TableName . '.Status = ' . STATUS_ACTIVE,
-					$object->TableName . '.LastRunStatus <> ' . ScheduledTask::LAST_RUN_RUNNING,
-				);
-
-				$sql =	$object->GetSelectSQL() . '
-						WHERE (' . implode(') AND (', $where_clause) . ')';
-				$scheduled_tasks = $this->Conn->Query($sql);
-
-				foreach ($scheduled_tasks as $scheduled_task_data) {
-					$this->Application->EventManager->runScheduledTask($scheduled_task_data);
-				}
-			}
-
-			$this->clearSelectedIDs($event);
-		}
-
-		/**
 		 * Loads schedule from database to virtual fields
 		 *
 		 * @param kEvent $event
@@ -303,4 +271,4 @@
 			$cron_helper->initUnit($event->Prefix, 'RunSchedule');
 
 		}
-	}
\ No newline at end of file
+	}
Index: tools/cron.php
===================================================================
--- tools/cron.php
+++ tools/cron.php
@@ -2,7 +2,7 @@
 /**
 * @version	$Id$
 * @package	In-Portal
-* @copyright	Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
+* @copyright	Copyright (C) 1997 - 2015 Intechnic. All rights reserved.
 * @license      GNU/GPL
 * In-Portal is Open Source software.
 * This means that this software may have been modified pursuant
@@ -12,27 +12,16 @@
 * See http://www.in-portal.org/license for copyright notices and details.
 */
 
-// Use either of lines above to invoke from cron:
-// */1 * * * * wget http://<server_address>/tools/cron.php -O /dev/null > /dev/null 2>&1
+// Use above line to invoke from cron:
 // */1 * * * * /usr/bin/php /path/to/site/tools/cron.php > /dev/null 2>&1
-$start = microtime(true);
 
-define('CRON', 1);
-//define('ADMIN', 1); // don't ever define, because this would drastically break down all links built from cron
-define('FULL_PATH', realpath(dirname(__FILE__) . '/..'));
-define('CMD_MODE', isset($argv) && count($argv) ? 1 : 0);
-
-if ( CMD_MODE ) {
-	define('DBG_SKIP_REPORTING', 1);
-	$_SERVER['REQUEST_URI'] = 'CRON';
-	$_SERVER['HTTP_USER_AGENT'] = 'gecko';
+if ( PHP_SAPI !== 'cli' ) {
+	echo 'This script is intended to be used from command-line only !';
+	exit(64);
 }
 
-include_once(FULL_PATH . '/core/kernel/startup.php');
-
-$application =& kApplication::Instance();
-$application->Init();
-
-// events from request are not processed, only predefined scheduled tasks
-$application->EventManager->runScheduledTasks(true);
+define('FULL_PATH', realpath(dirname(__FILE__) . '/..'));
 
+$exit_code = 0;
+passthru(FULL_PATH . '/in-portal scheduled-task:run', $exit_code);
+exit($exit_code);