diff --git a/core/Command/User/Setting.php b/core/Command/User/Setting.php
new file mode 100644
index 0000000000000000000000000000000000000000..7a62b5529b3e1baaae0fb7eb9fb33e152f6f7ad1
--- /dev/null
+++ b/core/Command/User/Setting.php
@@ -0,0 +1,226 @@
+<?php
+/**
+ * @author Joas Schilling <coding@schilljs.com>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OC\Core\Command\User;
+
+use OC\Core\Command\Base;
+use OCP\IConfig;
+use OCP\IDBConnection;
+use OCP\IUserManager;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Input\InputArgument;
+
+class Setting extends Base {
+	/** @var IUserManager */
+	protected $userManager;
+
+	/** @var IConfig */
+	protected $config;
+
+	/** @var IDBConnection */
+	protected $connection;
+
+	/**
+	 * @param IUserManager $userManager
+	 * @param IConfig $config
+	 * @param IDBConnection $connection
+	 */
+	public function __construct(IUserManager $userManager, IConfig $config, IDBConnection $connection) {
+		parent::__construct();
+		$this->userManager = $userManager;
+		$this->config = $config;
+		$this->connection = $connection;
+	}
+
+	protected function configure() {
+		parent::configure();
+		$this
+			->setName('user:setting')
+			->setDescription('Read and modify user settings')
+			->addArgument(
+				'uid',
+				InputArgument::REQUIRED,
+				'User ID used to login'
+			)
+			->addArgument(
+				'app',
+				InputArgument::OPTIONAL,
+				'Restrict the settings to a given app',
+				''
+			)
+			->addArgument(
+				'key',
+				InputArgument::OPTIONAL,
+				'Setting key to set, get or delete',
+				''
+			)
+			->addOption(
+				'ignore-missing-user',
+				null,
+				InputOption::VALUE_NONE,
+				'Use this option to ignore errors when the user does not exist'
+			)
+
+			// Get
+			->addOption(
+				'default-value',
+				null,
+				InputOption::VALUE_REQUIRED,
+				'(Only applicable on get) If no default value is set and the config does not exist, the command will exit with 1'
+			)
+
+			// Set
+			->addArgument(
+				'value',
+				InputArgument::OPTIONAL,
+				'The new value of the setting',
+				null
+			)
+			->addOption(
+				'update-only',
+				null,
+				InputOption::VALUE_NONE,
+				'Only updates the value, if it is not set before, it is not being added'
+			)
+
+			// Delete
+			->addOption(
+				'delete',
+				null,
+				InputOption::VALUE_NONE,
+				'Specify this option to delete the config'
+			)
+			->addOption(
+				'error-if-not-exists',
+				null,
+				InputOption::VALUE_NONE,
+				'Checks whether the setting exists before deleting it'
+			)
+		;
+	}
+
+	protected function checkInput(InputInterface $input) {
+		$uid = $input->getArgument('uid');
+		if (!$input->getOption('ignore-missing-user') && !$this->userManager->userExists($uid)) {
+			throw new \InvalidArgumentException('The user "' . $uid . '" does not exists.');
+		}
+
+		if ($input->getArgument('key') === '' && $input->hasParameterOption('--default-value')) {
+			throw new \InvalidArgumentException('The "default-value" option can only be used when specifying a key.');
+		}
+
+		if ($input->getArgument('key') === '' && $input->getArgument('value') !== null) {
+			throw new \InvalidArgumentException('The value argument can only be used when specifying a key.');
+		}
+		if ($input->getArgument('value') !== null && $input->hasParameterOption('--default-value')) {
+			throw new \InvalidArgumentException('The value argument can not be used together with "default-value".');
+		}
+		if ($input->getOption('update-only') && $input->getArgument('value') === null) {
+			throw new \InvalidArgumentException('The "update-only" option can only be used together with "value".');
+		}
+
+		if ($input->getArgument('key') === '' && $input->getOption('delete')) {
+			throw new \InvalidArgumentException('The "delete" option can only be used when specifying a key.');
+		}
+		if ($input->getOption('delete') && $input->hasParameterOption('--default-value')) {
+			throw new \InvalidArgumentException('The "delete" option can not be used together with "default-value".');
+		}
+		if ($input->getOption('delete') && $input->getArgument('value') !== null) {
+			throw new \InvalidArgumentException('The "delete" option can not be used together with "value".');
+		}
+		if ($input->getOption('error-if-not-exists') && !$input->getOption('delete')) {
+			throw new \InvalidArgumentException('The "error-if-not-exists" option can only be used together with "delete".');
+		}
+	}
+
+	protected function execute(InputInterface $input, OutputInterface $output) {
+		try {
+			$this->checkInput($input);
+		} catch (\InvalidArgumentException $e) {
+			$output->writeln('<error>' . $e->getMessage() . '</error>');
+			return 1;
+		}
+
+		$uid = $input->getArgument('uid');
+		$app = $input->getArgument('app');
+		$key = $input->getArgument('key');
+
+		if ($key !== '') {
+			$value = $this->config->getUserValue($uid, $app, $key, null);
+			if ($input->getArgument('value') !== null) {
+				if ($input->hasParameterOption('--update-only') && $value === null) {
+					$output->writeln('<error>The setting does not exist for user "' . $uid . '".</error>');
+					return 1;
+				}
+
+				$this->config->setUserValue($uid, $app, $key, $input->getArgument('value'));
+				return 0;
+
+			} else if ($input->hasParameterOption('--delete')) {
+				if ($input->hasParameterOption('--error-if-not-exists') && $value === null) {
+					$output->writeln('<error>The setting does not exist for user "' . $uid . '".</error>');
+					return 1;
+				}
+
+				$this->config->deleteUserValue($uid, $app, $key);
+				return 0;
+
+			} else if ($value !== null) {
+				$output->writeln($value);
+				return 0;
+			} else {
+				if ($input->hasParameterOption('--default-value')) {
+					$output->writeln($input->getOption('default-value'));
+					return 0;
+				} else {
+					$output->writeln('<error>The setting does not exist for user "' . $uid . '".</error>');
+					return 1;
+				}
+			}
+		} else {
+			$settings = $this->getUserSettings($uid, $app);
+			$this->writeArrayInOutputFormat($input, $output, $settings);
+			return 0;
+		}
+	}
+
+	protected function getUserSettings($uid, $app) {
+		$query = $this->connection->getQueryBuilder();
+		$query->select('*')
+			->from('preferences')
+			->where($query->expr()->eq('userid', $query->createNamedParameter($uid)));
+
+		if ($app !== '') {
+			$query->andWhere($query->expr()->eq('appid', $query->createNamedParameter($app)));
+		}
+
+		$result = $query->execute();
+		$settings = [];
+		while ($row = $result->fetch()) {
+			$settings[$row['appid']][$row['configkey']] = $row['configvalue'];
+		}
+		$result->closeCursor();
+
+		return $settings;
+	}
+}
diff --git a/core/register_command.php b/core/register_command.php
index ebb6ce8b7235b3ed8e295e1dbe7d5db90ac79152..91b00df20f13d6c053e1b767963bd8084d5fccec 100644
--- a/core/register_command.php
+++ b/core/register_command.php
@@ -136,6 +136,7 @@ if (\OC::$server->getConfig()->getSystemValue('installed', false)) {
 	$application->add(new OC\Core\Command\User\LastSeen(\OC::$server->getUserManager()));
 	$application->add(new OC\Core\Command\User\Report(\OC::$server->getUserManager()));
 	$application->add(new OC\Core\Command\User\ResetPassword(\OC::$server->getUserManager()));
+	$application->add(new OC\Core\Command\User\Setting(\OC::$server->getUserManager(), \OC::$server->getConfig(), \OC::$server->getDatabaseConnection()));
 
 	$application->add(new OC\Core\Command\Security\ListCertificates(\OC::$server->getCertificateManager(null), \OC::$server->getL10N('core')));
 	$application->add(new OC\Core\Command\Security\ImportCertificate(\OC::$server->getCertificateManager(null)));
diff --git a/tests/Core/Command/User/SettingTest.php b/tests/Core/Command/User/SettingTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..002e8dfef2fb5adf9b3cd67b68a6e75cbe625a77
--- /dev/null
+++ b/tests/Core/Command/User/SettingTest.php
@@ -0,0 +1,464 @@
+<?php
+/**
+ * @author Joas Schilling <coding@schilljs.com>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace Tests\Core\Command\User;
+
+
+use OC\Core\Command\User\Setting;
+use Test\TestCase;
+
+class SettingTest extends TestCase {
+	/** @var \OCP\IUserManager|\PHPUnit_Framework_MockObject_MockObject */
+	protected $userManager;
+	/** @var \OCP\IConfig|\PHPUnit_Framework_MockObject_MockObject */
+	protected $config;
+	/** @var \OCP\IDBConnection|\PHPUnit_Framework_MockObject_MockObject */
+	protected $connection;
+	/** @var \Symfony\Component\Console\Input\InputInterface|\PHPUnit_Framework_MockObject_MockObject */
+	protected $consoleInput;
+	/** @var \Symfony\Component\Console\Output\OutputInterface|\PHPUnit_Framework_MockObject_MockObject */
+	protected $consoleOutput;
+
+	protected function setUp() {
+		parent::setUp();
+
+		$this->userManager = $this->getMockBuilder('OCP\IUserManager')
+			->disableOriginalConstructor()
+			->getMock();
+		$this->config = $this->getMockBuilder('OCP\IConfig')
+			->disableOriginalConstructor()
+			->getMock();
+		$this->connection = $this->getMockBuilder('OCP\IDBConnection')
+			->disableOriginalConstructor()
+			->getMock();
+		$this->consoleInput = $this->getMockBuilder('Symfony\Component\Console\Input\InputInterface')
+			->disableOriginalConstructor()
+			->getMock();
+		$this->consoleOutput = $this->getMockBuilder('Symfony\Component\Console\Output\OutputInterface')
+			->disableOriginalConstructor()
+			->getMock();
+	}
+
+	public function getCommand(array $methods = []) {
+		if (empty($methods)) {
+			return new Setting($this->userManager, $this->config, $this->connection);
+		} else {
+			$mock = $this->getMockBuilder('OC\Core\Command\User\Setting')
+				->setConstructorArgs([
+					$this->userManager,
+					$this->config,
+					$this->connection,
+				])
+				->setMethods($methods)
+				->getMock();
+			return $mock;
+		}
+
+	}
+
+	public function dataCheckInput() {
+		return [
+			[
+				[['uid', 'username']],
+				[['ignore-missing-user', true]],
+				[],
+				false,
+				false,
+			],
+			[
+				[['uid', 'username']],
+				[['ignore-missing-user', false]],
+				[],
+				null,
+				'The user "username" does not exists.',
+			],
+
+			[
+				[['uid', 'username'], ['key', 'configkey']],
+				[['ignore-missing-user', true]],
+				[['--default-value', true]],
+				false,
+				false,
+			],
+			[
+				[['uid', 'username'], ['key', '']],
+				[['ignore-missing-user', true]],
+				[['--default-value', true]],
+				false,
+				'The "default-value" option can only be used when specifying a key.',
+			],
+
+			[
+				[['uid', 'username'], ['key', 'configkey'], ['value', '']],
+				[['ignore-missing-user', true]],
+				[],
+				false,
+				false,
+			],
+			[
+				[['uid', 'username'], ['key', ''], ['value', '']],
+				[['ignore-missing-user', true]],
+				[],
+				false,
+				'The value argument can only be used when specifying a key.',
+			],
+			[
+				[['uid', 'username'], ['key', 'configkey'], ['value', '']],
+				[['ignore-missing-user', true]],
+				[['--default-value', true]],
+				false,
+				'The value argument can not be used together with "default-value".',
+			],
+			[
+				[['uid', 'username'], ['key', 'configkey'], ['value', '']],
+				[['ignore-missing-user', true], ['update-only', true]],
+				[],
+				false,
+				false,
+			],
+			[
+				[['uid', 'username'], ['key', 'configkey'], ['value', null]],
+				[['ignore-missing-user', true], ['update-only', true]],
+				[],
+				false,
+				'The "update-only" option can only be used together with "value".',
+			],
+
+			[
+				[['uid', 'username'], ['key', 'configkey']],
+				[['ignore-missing-user', true], ['delete', true]],
+				[],
+				false,
+				false,
+			],
+			[
+				[['uid', 'username'], ['key', '']],
+				[['ignore-missing-user', true], ['delete', true]],
+				[],
+				false,
+				'The "delete" option can only be used when specifying a key.',
+			],
+			[
+				[['uid', 'username'], ['key', 'configkey']],
+				[['ignore-missing-user', true], ['delete', true]],
+				[['--default-value', true]],
+				false,
+				'The "delete" option can not be used together with "default-value".',
+			],
+			[
+				[['uid', 'username'], ['key', 'configkey'], ['value', '']],
+				[['ignore-missing-user', true], ['delete', true]],
+				[],
+				false,
+				'The "delete" option can not be used together with "value".',
+			],
+			[
+				[['uid', 'username'], ['key', 'configkey']],
+				[['ignore-missing-user', true], ['delete', true], ['error-if-not-exists', true]],
+				[],
+				false,
+				false,
+			],
+			[
+				[['uid', 'username'], ['key', 'configkey']],
+				[['ignore-missing-user', true], ['delete', false], ['error-if-not-exists', true]],
+				[],
+				false,
+				'The "error-if-not-exists" option can only be used together with "delete".',
+			],
+		];
+	}
+
+	/**
+	 * @dataProvider dataCheckInput
+	 *
+	 * @param array $arguments
+	 * @param array $options
+	 * @param array $parameterOptions
+	 * @param mixed $user
+	 * @param string $expectedException
+	 */
+	public function testCheckInput($arguments, $options, $parameterOptions, $user, $expectedException) {
+		$this->consoleInput->expects($this->any())
+			->method('getArgument')
+			->willReturnMap($arguments);
+		$this->consoleInput->expects($this->any())
+			->method('getOption')
+			->willReturnMap($options);
+		$this->consoleInput->expects($this->any())
+			->method('hasParameterOption')
+			->willReturnMap($parameterOptions);
+
+		if ($user !== false) {
+			$this->userManager->expects($this->once())
+				->method('userExists')
+				->willReturn($user);
+		}
+
+		$command = $this->getCommand();
+		try {
+			$this->invokePrivate($command, 'checkInput', [$this->consoleInput]);
+			$this->assertFalse($expectedException);
+		} catch (\InvalidArgumentException $e) {
+			$this->assertEquals($expectedException, $e->getMessage());
+		}
+	}
+
+	public function testCheckInputExceptionCatch() {
+		$command = $this->getCommand(['checkInput']);
+		$command->expects($this->once())
+			->method('checkInput')
+			->willThrowException(new \InvalidArgumentException('test'));
+
+		$this->consoleOutput->expects($this->once())
+			->method('writeln')
+			->with('<error>test</error>');
+
+		$this->assertEquals(1, $this->invokePrivate($command, 'execute', [$this->consoleInput, $this->consoleOutput]));
+	}
+
+	public function dataExecuteDelete() {
+		return [
+			['config', false, null, 0],
+			['config', true, null, 0],
+			[null, false, null, 0],
+			[null, true, '<error>The setting does not exist for user "username".</error>', 1],
+		];
+	}
+
+	/**
+	 * @dataProvider dataExecuteDelete
+	 *
+	 * @param string|null $value
+	 * @param bool $errorIfNotExists
+	 * @param string $expectedLine
+	 * @param int $expectedReturn
+	 */
+	public function testExecuteDelete($value, $errorIfNotExists, $expectedLine, $expectedReturn) {
+		$command = $this->getCommand([
+			'writeArrayInOutputFormat',
+			'checkInput',
+			'getUserSettings',
+		]);
+
+		$this->consoleInput->expects($this->any())
+			->method('getArgument')
+			->willReturnMap([
+				['uid', 'username'],
+				['app', 'appname'],
+				['key', 'configkey'],
+			]);
+
+		$command->expects($this->once())
+			->method('checkInput');
+
+		$this->config->expects($this->once())
+			->method('getUserValue')
+			->with('username', 'appname', 'configkey', null)
+			->willReturn($value);
+
+		$this->consoleInput->expects($this->atLeastOnce())
+			->method('hasParameterOption')
+			->willReturnMap([
+				['--delete', true],
+				['--error-if-not-exists', $errorIfNotExists],
+			]);
+
+		if ($expectedLine === null) {
+			$this->consoleOutput->expects($this->never())
+				->method('writeln');
+			$this->config->expects($this->once())
+				->method('deleteUserValue')
+				->with('username', 'appname', 'configkey');
+
+		} else {
+			$this->consoleOutput->expects($this->once())
+				->method('writeln')
+				->with($expectedLine);
+			$this->config->expects($this->never())
+				->method('deleteUserValue');
+		}
+
+		$this->assertEquals($expectedReturn, $this->invokePrivate($command, 'execute', [$this->consoleInput, $this->consoleOutput]));
+	}
+
+	public function dataExecuteSet() {
+		return [
+			['config', false, null, 0],
+			['config', true, null, 0],
+			[null, false, null, 0],
+			[null, true, '<error>The setting does not exist for user "username".</error>', 1],
+		];
+	}
+
+	/**
+	 * @dataProvider dataExecuteSet
+	 *
+	 * @param string|null $value
+	 * @param bool $updateOnly
+	 * @param string $expectedLine
+	 * @param int $expectedReturn
+	 */
+	public function testExecuteSet($value, $updateOnly, $expectedLine, $expectedReturn) {
+		$command = $this->getCommand([
+			'writeArrayInOutputFormat',
+			'checkInput',
+			'getUserSettings',
+		]);
+
+		$this->consoleInput->expects($this->atLeast(4))
+			->method('getArgument')
+			->willReturnMap([
+				['uid', 'username'],
+				['app', 'appname'],
+				['key', 'configkey'],
+				['value', 'setValue'],
+			]);
+
+		$command->expects($this->once())
+			->method('checkInput');
+
+		$this->config->expects($this->once())
+			->method('getUserValue')
+			->with('username', 'appname', 'configkey', null)
+			->willReturn($value);
+
+		$this->consoleInput->expects($this->atLeastOnce())
+			->method('hasParameterOption')
+			->willReturnMap([
+				['--update-only', $updateOnly],
+			]);
+
+		if ($expectedLine === null) {
+			$this->consoleOutput->expects($this->never())
+				->method('writeln');
+
+			$this->consoleInput->expects($this->never())
+				->method('getOption');
+
+			$this->config->expects($this->once())
+				->method('setUserValue')
+				->with('username', 'appname', 'configkey', 'setValue');
+		} else {
+			$this->consoleOutput->expects($this->once())
+				->method('writeln')
+				->with($expectedLine);
+			$this->config->expects($this->never())
+				->method('setUserValue');
+		}
+
+		$this->assertEquals($expectedReturn, $this->invokePrivate($command, 'execute', [$this->consoleInput, $this->consoleOutput]));
+	}
+
+	public function dataExecuteGet() {
+		return [
+			['config', null, 'config', 0],
+			[null, 'config', 'config', 0],
+			[null, null, '<error>The setting does not exist for user "username".</error>', 1],
+		];
+	}
+
+	/**
+	 * @dataProvider dataExecuteGet
+	 *
+	 * @param string|null $value
+	 * @param string|null $defaultValue
+	 * @param string $expectedLine
+	 * @param int $expectedReturn
+	 */
+	public function testExecuteGet($value, $defaultValue, $expectedLine, $expectedReturn) {
+		$command = $this->getCommand([
+			'writeArrayInOutputFormat',
+			'checkInput',
+			'getUserSettings',
+		]);
+
+		$this->consoleInput->expects($this->any())
+			->method('getArgument')
+			->willReturnMap([
+				['uid', 'username'],
+				['app', 'appname'],
+				['key', 'configkey'],
+			]);
+
+		$command->expects($this->once())
+			->method('checkInput');
+
+		$this->config->expects($this->once())
+			->method('getUserValue')
+			->with('username', 'appname', 'configkey', null)
+			->willReturn($value);
+
+		if ($value === null) {
+			if ($defaultValue === null) {
+				$this->consoleInput->expects($this->atLeastOnce())
+					->method('hasParameterOption')
+					->willReturnMap([
+						['--default-value', false],
+					]);
+			} else {
+				$this->consoleInput->expects($this->atLeastOnce())
+					->method('hasParameterOption')
+					->willReturnMap([
+						['--default-value', true],
+					]);
+				$this->consoleInput->expects($this->once())
+					->method('getOption')
+					->with('default-value')
+					->willReturn($defaultValue);
+			}
+		}
+
+		$this->consoleOutput->expects($this->once())
+			->method('writeln')
+			->with($expectedLine);
+
+		$this->assertEquals($expectedReturn, $this->invokePrivate($command, 'execute', [$this->consoleInput, $this->consoleOutput]));
+	}
+
+	public function testExecuteList() {
+		$command = $this->getCommand([
+			'writeArrayInOutputFormat',
+			'checkInput',
+			'getUserSettings',
+		]);
+
+		$this->consoleInput->expects($this->any())
+			->method('getArgument')
+			->willReturnMap([
+				['uid', 'username'],
+				['app', 'appname'],
+				['key', ''],
+			]);
+
+		$command->expects($this->once())
+			->method('checkInput');
+		$command->expects($this->once())
+			->method('getUserSettings')
+			->willReturn(['settings']);
+		$command->expects($this->once())
+			->method('writeArrayInOutputFormat')
+			->with($this->consoleInput, $this->consoleOutput, ['settings']);
+
+
+		$this->assertEquals(0, $this->invokePrivate($command, 'execute', [$this->consoleInput, $this->consoleOutput]));
+	}
+}